From e40dc71400bff4f26945bc30737f75f476126519 Mon Sep 17 00:00:00 2001 From: Magnus Lundborg Date: Tue, 9 Dec 2014 13:43:16 +0100 Subject: [PATCH] TNG version 1.7.3 Corresponds to commit e862ebe8 in the TNG repository. Large parts of the TNG code have been rewritten to avoid code duplication. Some functions have been combined. Summary of additional changes (see git log for full details): Bug fixes: Fixed bug reading last frame and time of last frame. Fix MingW build Fixed bug reading non-particle data. Check that ZLib is available before using it. Fixed bug when appending to trajectory. New functions: tng_util_num_frames_with_data_of_block_id_get() Fixed compiler warnings Improved testing suite Change-Id: I97334b1d93f21646fe1625e65e5fcdf38a0450d9 --- docs/install-guide/index.rst | 2 +- src/external/tng_io/BuildTNG.cmake | 6 +- src/external/tng_io/Doxyfile.in | 6 +- .../tng_io/include/compression/bwlzh.h | 26 +- src/external/tng_io/include/compression/bwt.h | 12 +- .../tng_io/include/compression/coder.h | 8 +- .../tng_io/include/compression/dict.h | 2 +- .../tng_io/include/compression/fixpoint.h | 8 +- .../tng_io/include/compression/huffman.h | 12 +- .../tng_io/include/compression/lz77.h | 10 +- .../tng_io/include/compression/merge_sort.h | 2 +- src/external/tng_io/include/compression/mtf.h | 16 +- src/external/tng_io/include/compression/rle.h | 8 +- .../tng_io/include/compression/tng_compress.h | 76 +- .../tng_io/include/compression/vals16.h | 8 +- .../tng_io/include/compression/warnmalloc.h | 4 +- .../tng_io/include/compression/widemuldiv.h | 13 +- src/external/tng_io/include/tng/tng_io.h | 393 +- src/external/tng_io/include/tng/tng_io_fwd.h | 6 +- src/external/tng_io/src/compression/bwlzh.c | 26 +- src/external/tng_io/src/compression/bwt.c | 32 +- src/external/tng_io/src/compression/coder.c | 53 +- src/external/tng_io/src/compression/dict.c | 18 +- .../tng_io/src/compression/fixpoint.c | 8 +- src/external/tng_io/src/compression/huffman.c | 16 +- src/external/tng_io/src/compression/huffmem.c | 10 +- src/external/tng_io/src/compression/lz77.c | 12 +- .../tng_io/src/compression/merge_sort.c | 6 +- src/external/tng_io/src/compression/mtf.c | 40 +- src/external/tng_io/src/compression/rle.c | 12 +- .../tng_io/src/compression/tng_compress.c | 166 +- src/external/tng_io/src/compression/vals16.c | 8 +- .../tng_io/src/compression/warnmalloc.c | 4 +- .../tng_io/src/compression/widemuldiv.c | 49 +- src/external/tng_io/src/compression/xtc2.c | 126 +- src/external/tng_io/src/compression/xtc3.c | 92 +- src/external/tng_io/src/lib/md5.c | 1 + src/external/tng_io/src/lib/tng_io.c | 16885 +++++++--------- src/external/tng_io/src/tests/md_openmp.c | 2 +- .../tng_io/src/tests/md_openmp_util.c | 2 +- .../tng_io/src/tests/tng_io_read_pos.c | 3 +- .../tng_io/src/tests/tng_io_read_pos_util.c | 3 +- .../tng_io/src/tests/tng_io_testing.c | 1088 +- .../tng_io/src/tests/tng_parallel_read.c | 3 +- 44 files changed, 9170 insertions(+), 10113 deletions(-) diff --git a/docs/install-guide/index.rst b/docs/install-guide/index.rst index 8c245f4245..86462019e3 100644 --- a/docs/install-guide/index.rst +++ b/docs/install-guide/index.rst @@ -289,7 +289,7 @@ Optional build components Motif/Lesstif libraries and header files. You may prefer to use third-party software for visualization, such as VMD_ or PyMol_. * An external TNG library for trajectory-file handling can be used, - but TNG 1.6 is bundled in the |Gromacs| source already + but TNG 1.7.3 is bundled in the |Gromacs| source already * zlib is used by TNG for compressing some kinds of trajectory data * Running the |Gromacs| test suite requires libxml2 * Building the |Gromacs| documentation requires ImageMagick, pdflatex, diff --git a/src/external/tng_io/BuildTNG.cmake b/src/external/tng_io/BuildTNG.cmake index ea77430cf9..a00d5b5e4e 100644 --- a/src/external/tng_io/BuildTNG.cmake +++ b/src/external/tng_io/BuildTNG.cmake @@ -4,10 +4,10 @@ set(TNG_ROOT_BINARY_DIR ${CMAKE_BINARY_DIR}/${TNG_ROOT_BINARY_DIR}) function (TNG_GENERATE_VERSION_H) set(TNG_MAJOR_VERSION "1") - set(TNG_MINOR_VERSION "6") - set(TNG_VERSION_PATCH_LEVEL "1") + set(TNG_MINOR_VERSION "7") + set(TNG_VERSION_PATCH_LEVEL "3") set(TNG_IO_VERSION "${TNG_MAJOR_VERSION}.${TNG_MINOR_VERSION}.${TNG_VERSION_PATCH_LEVEL}") - set(TNG_API_VERSION "6") + set(TNG_API_VERSION "7") configure_file(${TNG_ROOT_SOURCE_DIR}/include/tng/version.h.in ${TNG_ROOT_BINARY_DIR}/include/tng/version.h) diff --git a/src/external/tng_io/Doxyfile.in b/src/external/tng_io/Doxyfile.in index 03ba55355a..27ca707b15 100644 --- a/src/external/tng_io/Doxyfile.in +++ b/src/external/tng_io/Doxyfile.in @@ -32,7 +32,7 @@ PROJECT_NAME = "TNG API" # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = "1.4" +PROJECT_NUMBER = "@TNG_IO_VERSION@" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer @@ -626,7 +626,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = @PROJECT_SOURCE_DIR@/src/lib @PROJECT_SOURCE_DIR@/include +INPUT = @PROJECT_SOURCE_DIR@/src/lib @PROJECT_SOURCE_DIR@/include/tng/ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is @@ -658,7 +658,7 @@ RECURSIVE = NO # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = @PROJECT_SOURCE_DIR@/src/lib/md5.c @PROJECT_SOURCE_DIR@/include/tng/md5.h @PROJECT_SOURCE_DIR@/include/tng/tng_io.hpp @PROJECT_SOURCE_DIR@/src/lib/tng_io.c +EXCLUDE = @PROJECT_SOURCE_DIR@/src/lib/md5.c @PROJECT_SOURCE_DIR@/include/tng/md5.h @PROJECT_SOURCE_DIR@/include/tng/tng_io.hpp @PROJECT_SOURCE_DIR@/src/lib/tng_io.c @PROJECT_SOURCE_DIR@/src/lib/tng_io_fortran.c # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded diff --git a/src/external/tng_io/include/compression/bwlzh.h b/src/external/tng_io/include/compression/bwlzh.h index 70d586a2d9..ce08f69cb8 100644 --- a/src/external/tng_io/include/compression/bwlzh.h +++ b/src/external/tng_io/include/compression/bwlzh.h @@ -17,28 +17,28 @@ allocated to be able to hold worst case. You can obtain this length conveniently by calling comp_get_buflen() */ -void DECLSPECDLLEXPORT bwlzh_compress(unsigned int *vals, int nvals, +void DECLSPECDLLEXPORT bwlzh_compress(unsigned int *vals, const int nvals, unsigned char *output, int *output_len); -void DECLSPECDLLEXPORT bwlzh_compress_no_lz77(unsigned int *vals, int nvals, +void DECLSPECDLLEXPORT bwlzh_compress_no_lz77(unsigned int *vals, const int nvals, unsigned char *output, int *output_len); -int DECLSPECDLLEXPORT bwlzh_get_buflen(int nvals); +int DECLSPECDLLEXPORT bwlzh_get_buflen(const int nvals); -void DECLSPECDLLEXPORT bwlzh_decompress(unsigned char *input, int nvals, +void DECLSPECDLLEXPORT bwlzh_decompress(unsigned char *input, const int nvals, unsigned int *vals); /* The routines below are mostly useful for testing, and for internal use by the library. */ -void DECLSPECDLLEXPORT bwlzh_compress_verbose(unsigned int *vals, int nvals, +void DECLSPECDLLEXPORT bwlzh_compress_verbose(unsigned int *vals, const int nvals, unsigned char *output, int *output_len); -void DECLSPECDLLEXPORT bwlzh_compress_no_lz77_verbose(unsigned int *vals, int nvals, +void DECLSPECDLLEXPORT bwlzh_compress_no_lz77_verbose(unsigned int *vals, const int nvals, unsigned char *output, int *output_len); -void DECLSPECDLLEXPORT bwlzh_decompress_verbose(unsigned char *input, int nvals, +void DECLSPECDLLEXPORT bwlzh_decompress_verbose(unsigned char *input, const int nvals, unsigned int *vals); /* Compress the integers (positive, small integers are preferable) @@ -47,12 +47,12 @@ void DECLSPECDLLEXPORT bwlzh_decompress_verbose(unsigned char *input, int nvals, to be able to hold worst case. You can obtain this length conveniently by calling comp_huff_buflen() */ -void Ptngc_comp_huff_compress(unsigned int *vals, int nvals, +void Ptngc_comp_huff_compress(unsigned int *vals, const int nvals, unsigned char *huffman, int *huffman_len); -int Ptngc_comp_huff_buflen(int nvals); +int Ptngc_comp_huff_buflen(const int nvals); -void Ptngc_comp_huff_decompress(unsigned char *huffman, int huffman_len, +void Ptngc_comp_huff_decompress(unsigned char *huffman, const int huffman_len, unsigned int *vals); @@ -62,11 +62,11 @@ void Ptngc_comp_huff_compress_verbose(unsigned int *vals, int nvals, unsigned char *huffman, int *huffman_len, int *huffdatalen, int *huffman_lengths,int *chosen_algo, - int isvals16); + const int isvals16); #define N_HUFFMAN_ALGO 3 -char *Ptngc_comp_get_huff_algo_name(int algo); -char *Ptngc_comp_get_algo_name(int algo); +char *Ptngc_comp_get_huff_algo_name(const int algo); +char *Ptngc_comp_get_algo_name(const int algo); #endif diff --git a/src/external/tng_io/include/compression/bwt.h b/src/external/tng_io/include/compression/bwt.h index 9f927f8226..fedfc3d0ad 100644 --- a/src/external/tng_io/include/compression/bwt.h +++ b/src/external/tng_io/include/compression/bwt.h @@ -12,15 +12,15 @@ #ifndef BWT_H #define BWT_H -void Ptngc_comp_to_bwt(unsigned int *vals, int nvals, +void Ptngc_comp_to_bwt(unsigned int *vals, const int nvals, unsigned int *output, int *index); -void Ptngc_comp_from_bwt(unsigned int *input, int nvals, int index, +void Ptngc_comp_from_bwt(unsigned int *input, const int nvals, int index, unsigned int *vals); -void Ptngc_bwt_merge_sort_inner(int *indices, int nvals,unsigned int *vals, - int start, int end, - unsigned int *nrepeat, - int *workarray); +void Ptngc_bwt_merge_sort_inner(int *indices, const int nvals, unsigned int *vals, + const int start, const int end, + unsigned int *nrepeat, + int *workarray); #endif diff --git a/src/external/tng_io/include/compression/coder.h b/src/external/tng_io/include/compression/coder.h index 34b56c1fe0..d714c82f6f 100644 --- a/src/external/tng_io/include/compression/coder.h +++ b/src/external/tng_io/include/compression/coder.h @@ -29,10 +29,10 @@ struct coder struct coder DECLSPECDLLEXPORT *Ptngc_coder_init(void); void DECLSPECDLLEXPORT Ptngc_coder_deinit(struct coder *coder); -unsigned char DECLSPECDLLEXPORT *Ptngc_pack_array(struct coder *coder,int *input, int *length, int coding, int coding_parameter, int natoms, int speed); -int DECLSPECDLLEXPORT Ptngc_unpack_array(struct coder *coder,unsigned char *packed,int *output, int length, int coding, int coding_parameter, int natoms); +unsigned char DECLSPECDLLEXPORT *Ptngc_pack_array(struct coder *coder,int *input, int *length, const int coding, const int coding_parameter, const int natoms, const int speed); +int DECLSPECDLLEXPORT Ptngc_unpack_array(struct coder *coder,unsigned char *packed,int *output, const int length, const int coding, const int coding_parameter, const int natoms); unsigned char DECLSPECDLLEXPORT *Ptngc_pack_array_xtc2(struct coder *coder,int *input, int *length); -int DECLSPECDLLEXPORT Ptngc_unpack_array_xtc2(struct coder *coder,unsigned char *packed,int *output, int length); +int DECLSPECDLLEXPORT Ptngc_unpack_array_xtc2(struct coder *coder, unsigned char *packed, int *output, const int length); unsigned char DECLSPECDLLEXPORT *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int speed); int DECLSPECDLLEXPORT Ptngc_unpack_array_xtc3(unsigned char *packed,int *output, int length, int natoms); @@ -40,7 +40,7 @@ void DECLSPECDLLEXPORT Ptngc_out8bits(struct coder *coder, unsigned char **outpu void DECLSPECDLLEXPORT Ptngc_pack_flush(struct coder *coder,unsigned char **output); void DECLSPECDLLEXPORT Ptngc_write_pattern(struct coder *coder,unsigned int pattern, int nbits, unsigned char **output); -void DECLSPECDLLEXPORT Ptngc_writebits(struct coder *coder,unsigned int value,int nbits, unsigned char **output_ptr); +void DECLSPECDLLEXPORT Ptngc_writebits(struct coder *coder, unsigned int value, const int nbits, unsigned char **output_ptr); void DECLSPECDLLEXPORT Ptngc_write32bits(struct coder *coder,unsigned int value,int nbits, unsigned char **output_ptr); void DECLSPECDLLEXPORT Ptngc_writemanybits(struct coder *coder,unsigned char *value,int nbits, unsigned char **output_ptr); diff --git a/src/external/tng_io/include/compression/dict.h b/src/external/tng_io/include/compression/dict.h index d66dd23ac1..26eed2736e 100644 --- a/src/external/tng_io/include/compression/dict.h +++ b/src/external/tng_io/include/compression/dict.h @@ -14,7 +14,7 @@ void Ptngc_comp_canonical_dict(unsigned int *dict, int *ndict); -void Ptngc_comp_make_dict_hist(unsigned int *vals, int nvals, +void Ptngc_comp_make_dict_hist(unsigned int *vals, const int nvals, unsigned int *dict, int *ndict, unsigned int *hist); diff --git a/src/external/tng_io/include/compression/fixpoint.h b/src/external/tng_io/include/compression/fixpoint.h index 6be748295b..7b6a66725e 100644 --- a/src/external/tng_io/include/compression/fixpoint.h +++ b/src/external/tng_io/include/compression/fixpoint.h @@ -17,16 +17,16 @@ typedef unsigned long fix_t; /* Positive double to 32 bit fixed point value */ -fix_t Ptngc_ud_to_fix_t(double d,double max); +fix_t Ptngc_ud_to_fix_t(double d, const double max); /* double to signed 32 bit fixed point value */ -fix_t Ptngc_d_to_fix_t(double d,double max); +fix_t Ptngc_d_to_fix_t(double d, const double max); /* 32 bit fixed point value to positive double */ -double Ptngc_fix_t_to_ud(fix_t f, double max); +double Ptngc_fix_t_to_ud(fix_t f, const double max); /* signed 32 bit fixed point value to double */ -double Ptngc_fix_t_to_d(fix_t f, double max); +double Ptngc_fix_t_to_d(fix_t f, const double max); /* Convert a floating point variable to two 32 bit integers with range -2.1e9 to 2.1e9 and precision to somewhere around 1e-9. */ diff --git a/src/external/tng_io/include/compression/huffman.h b/src/external/tng_io/include/compression/huffman.h index 49347de2ba..f2ce1875b6 100644 --- a/src/external/tng_io/include/compression/huffman.h +++ b/src/external/tng_io/include/compression/huffman.h @@ -12,8 +12,8 @@ #ifndef HUFFMAN_H #define HUFFMAN_H -void Ptngc_comp_conv_to_huffman(unsigned int *vals, int nvals, - unsigned int *dict, int ndict, +void Ptngc_comp_conv_to_huffman(unsigned int *vals, const int nvals, + unsigned int *dict, const int ndict, unsigned int *prob, unsigned char *huffman, int *huffman_len, @@ -23,11 +23,11 @@ void Ptngc_comp_conv_to_huffman(unsigned int *vals, int nvals, int *huffman_dict_unpackedlen); void Ptngc_comp_conv_from_huffman(unsigned char *huffman, - unsigned int *vals, int nvals, - int ndict, + unsigned int *vals, const int nvals, + const int ndict, unsigned char *huffman_dict, - int huffman_dictlen, + const int huffman_dictlen, unsigned int *huffman_dict_unpacked, - int huffman_dict_unpackedlen); + const int huffman_dict_unpackedlen); #endif diff --git a/src/external/tng_io/include/compression/lz77.h b/src/external/tng_io/include/compression/lz77.h index ad37e5b30c..d4a4beb856 100644 --- a/src/external/tng_io/include/compression/lz77.h +++ b/src/external/tng_io/include/compression/lz77.h @@ -12,14 +12,14 @@ #ifndef LZ77_H #define LZ77_H -void Ptngc_comp_to_lz77(unsigned int *vals, int nvals, +void Ptngc_comp_to_lz77(unsigned int *vals, const int nvals, unsigned int *data, int *ndata, unsigned int *len, int *nlens, unsigned int *offsets, int *noffsets); -void Ptngc_comp_from_lz77(unsigned int *data, int ndata, - unsigned int *len, int nlens, - unsigned int *offsets, int noffsets, - unsigned int *vals, int nvals); +void Ptngc_comp_from_lz77(unsigned int *data, const int ndata, + unsigned int *len, const int nlens, + unsigned int *offsets, const int noffsets, + unsigned int *vals, const int nvals); #endif diff --git a/src/external/tng_io/include/compression/merge_sort.h b/src/external/tng_io/include/compression/merge_sort.h index 48ab41038a..f8aaeb79ba 100644 --- a/src/external/tng_io/include/compression/merge_sort.h +++ b/src/external/tng_io/include/compression/merge_sort.h @@ -12,7 +12,7 @@ #ifndef MERGE_SORT_H #define MERGE_SORT_H -void Ptngc_merge_sort(void *base, size_t nmemb, size_t size, +void Ptngc_merge_sort(void *base, const size_t nmemb, const size_t size, int (*compar)(const void *v1,const void *v2,const void *private), void *private); diff --git a/src/external/tng_io/include/compression/mtf.h b/src/external/tng_io/include/compression/mtf.h index bc4b2c81f5..3dc9ace1ea 100644 --- a/src/external/tng_io/include/compression/mtf.h +++ b/src/external/tng_io/include/compression/mtf.h @@ -12,24 +12,24 @@ #ifndef MTF_H #define MTF_H -void Ptngc_comp_conv_to_mtf(unsigned int *vals, int nvals, - unsigned int *dict, int ndict, +void Ptngc_comp_conv_to_mtf(unsigned int *vals, const int nvals, + unsigned int *dict, const int ndict, unsigned int *valsmtf); -void Ptngc_comp_conv_from_mtf(unsigned int *valsmtf, int nvals, - unsigned int *dict, int ndict, +void Ptngc_comp_conv_from_mtf(unsigned int *valsmtf, const int nvals, + unsigned int *dict, const int ndict, unsigned int *vals); -void Ptngc_comp_conv_to_mtf_partial(unsigned int *vals, int nvals, +void Ptngc_comp_conv_to_mtf_partial(unsigned int *vals, const int nvals, unsigned int *valsmtf); -void Ptngc_comp_conv_from_mtf_partial(unsigned int *valsmtf, int nvals, +void Ptngc_comp_conv_from_mtf_partial(unsigned int *valsmtf, const int nvals, unsigned int *vals); -void Ptngc_comp_conv_to_mtf_partial3(unsigned int *vals, int nvals, +void Ptngc_comp_conv_to_mtf_partial3(unsigned int *vals, const int nvals, unsigned char *valsmtf); -void Ptngc_comp_conv_from_mtf_partial3(unsigned char *valsmtf, int nvals, +void Ptngc_comp_conv_from_mtf_partial3(unsigned char *valsmtf, const int nvals, unsigned int *vals); #endif diff --git a/src/external/tng_io/include/compression/rle.h b/src/external/tng_io/include/compression/rle.h index c6d47069b5..3665dd0717 100644 --- a/src/external/tng_io/include/compression/rle.h +++ b/src/external/tng_io/include/compression/rle.h @@ -12,11 +12,11 @@ #ifndef RLE_H #define RLE_H -void Ptngc_comp_conv_to_rle(unsigned int *vals, int nvals, - unsigned int *rle, int *nrle, - int min_rle); +void Ptngc_comp_conv_to_rle(unsigned int *vals, const int nvals, + unsigned int *rle, int *nrle, + const int min_rle); void Ptngc_comp_conv_from_rle(unsigned int *rle, - unsigned int *vals, int nvals); + unsigned int *vals, const int nvals); #endif diff --git a/src/external/tng_io/include/compression/tng_compress.h b/src/external/tng_io/include/compression/tng_compress.h index c8b8db1ead..0082ba35d6 100644 --- a/src/external/tng_io/include/compression/tng_compress.h +++ b/src/external/tng_io/include/compression/tng_compress.h @@ -50,18 +50,18 @@ If too large values are input (compared to the precision), NULL is returned. */ -char DECLSPECDLLEXPORT *tng_compress_pos(double *pos, int natoms, int nframes, - double desired_precision, - int speed, int *algo, +char DECLSPECDLLEXPORT *tng_compress_pos(double *pos, const int natoms, const int nframes, + const double desired_precision, + const int speed, int *algo, int *nitems); -char DECLSPECDLLEXPORT *tng_compress_pos_float(float *pos, int natoms, int nframes, - float desired_precision, - int speed, int *algo, +char DECLSPECDLLEXPORT *tng_compress_pos_float(float *pos, const int natoms, const int nframes, + const float desired_precision, + const int speed, int *algo, int *nitems); -char DECLSPECDLLEXPORT *tng_compress_pos_int(int *pos, int natoms, int nframes, - unsigned long prec_hi, unsigned long prec_lo, +char DECLSPECDLLEXPORT *tng_compress_pos_int(int *pos, const int natoms, const int nframes, + const unsigned long prec_hi, const unsigned long prec_lo, int speed,int *algo, int *nitems); @@ -90,21 +90,21 @@ char DECLSPECDLLEXPORT *tng_compress_pos_int(int *pos, int natoms, int nframes, by calling tng_compress_nalgo */ -char DECLSPECDLLEXPORT *tng_compress_pos_find_algo(double *pos, int natoms, int nframes, - double desired_precision, - int speed, +char DECLSPECDLLEXPORT *tng_compress_pos_find_algo(double *pos, const int natoms, const int nframes, + const double desired_precision, + const int speed, int *algo, int *nitems); -char DECLSPECDLLEXPORT *tng_compress_pos_float_find_algo(float *pos, int natoms, int nframes, - float desired_precision, - int speed, +char DECLSPECDLLEXPORT *tng_compress_pos_float_find_algo(float *pos, const int natoms, const int nframes, + const float desired_precision, + const int speed, int *algo, int *nitems); -char DECLSPECDLLEXPORT *tng_compress_pos_int_find_algo(int *pos, int natoms, int nframes, - unsigned long prec_hi, unsigned long prec_lo, - int speed,int *algo, +char DECLSPECDLLEXPORT *tng_compress_pos_int_find_algo(int *pos, const int natoms, const int nframes, + const unsigned long prec_hi, const unsigned long prec_lo, + const int speed, int *algo, int *nitems); /* This returns the number of integers required for the storage of the algorithm @@ -116,36 +116,36 @@ int DECLSPECDLLEXPORT tng_compress_nalgo(void); selection for velocities is different, so the position and velocities routines should not be mixed. */ -char DECLSPECDLLEXPORT *tng_compress_vel(double *vel, int natoms, int nframes, - double desired_precision, - int speed, int *algo, +char DECLSPECDLLEXPORT *tng_compress_vel(double *vel, const int natoms, const int nframes, + const double desired_precision, + const int speed, int *algo, int *nitems); -char DECLSPECDLLEXPORT *tng_compress_vel_float(float *vel, int natoms, int nframes, - float desired_precision, - int speed, int *algo, +char DECLSPECDLLEXPORT *tng_compress_vel_float(float *vel, const int natoms, const int nframes, + const float desired_precision, + const int speed, int *algo, int *nitems); -char DECLSPECDLLEXPORT *tng_compress_vel_int(int *vel, int natoms, int nframes, - unsigned long prec_hi, unsigned long prec_lo, +char DECLSPECDLLEXPORT *tng_compress_vel_int(int *vel, const int natoms, const int nframes, + const unsigned long prec_hi, const unsigned long prec_lo, int speed, int *algo, int *nitems); -char DECLSPECDLLEXPORT *tng_compress_vel_find_algo(double *vel, int natoms, int nframes, - double desired_precision, - int speed, +char DECLSPECDLLEXPORT *tng_compress_vel_find_algo(double *vel, const int natoms, const int nframes, + const double desired_precision, + const int speed, int *algo, int *nitems); -char DECLSPECDLLEXPORT *tng_compress_vel_float_find_algo(float *vel, int natoms, int nframes, - float desired_precision, - int speed, +char DECLSPECDLLEXPORT *tng_compress_vel_float_find_algo(float *vel, const int natoms, const int nframes, + const float desired_precision, + const int speed, int *algo, int *nitems); -char DECLSPECDLLEXPORT *tng_compress_vel_int_find_algo(int *vel, int natoms, int nframes, - unsigned long prec_hi, unsigned long prec_lo, - int speed, +char DECLSPECDLLEXPORT *tng_compress_vel_int_find_algo(int *vel, const int natoms, const int nframes, + const unsigned long prec_hi, const unsigned long prec_lo, + const int speed, int *algo, int *nitems); @@ -170,12 +170,12 @@ int DECLSPECDLLEXPORT tng_compress_uncompress_int(char *data,int *posvel, unsign /* This converts a block of integers, as obtained from tng_compress_uncompress_int, to floating point values either double precision or single precision. */ -void DECLSPECDLLEXPORT tng_compress_int_to_double(int *posvel_int,unsigned long prec_hi, unsigned long prec_lo, - int natoms,int nframes, +void DECLSPECDLLEXPORT tng_compress_int_to_double(int *posvel_int, const unsigned long prec_hi, const unsigned long prec_lo, + const int natoms, const int nframes, double *posvel_double); -void DECLSPECDLLEXPORT tng_compress_int_to_float(int *posvel_int,unsigned long prec_hi, unsigned long prec_lo, - int natoms,int nframes, +void DECLSPECDLLEXPORT tng_compress_int_to_float(int *posvel_int, const unsigned long prec_hi, const unsigned long prec_lo, + const int natoms, const int nframes, float *posvel_float); diff --git a/src/external/tng_io/include/compression/vals16.h b/src/external/tng_io/include/compression/vals16.h index 4585755640..ba1b8fb2e3 100644 --- a/src/external/tng_io/include/compression/vals16.h +++ b/src/external/tng_io/include/compression/vals16.h @@ -12,10 +12,10 @@ #ifndef VALS16_H #define VALS16_H -void Ptngc_comp_conv_to_vals16(unsigned int *vals,int nvals, - unsigned int *vals16, int *nvals16); +void Ptngc_comp_conv_to_vals16(unsigned int *vals, const int nvals, + unsigned int *vals16, int *nvals16); -void Ptngc_comp_conv_from_vals16(unsigned int *vals16,int nvals16, - unsigned int *vals, int *nvals); +void Ptngc_comp_conv_from_vals16(unsigned int *vals16, const int nvals16, + unsigned int *vals, int *nvals); #endif diff --git a/src/external/tng_io/include/compression/warnmalloc.h b/src/external/tng_io/include/compression/warnmalloc.h index 44442714c7..aa631117ed 100644 --- a/src/external/tng_io/include/compression/warnmalloc.h +++ b/src/external/tng_io/include/compression/warnmalloc.h @@ -14,11 +14,11 @@ #include "../compression/tng_compress.h" -void DECLSPECDLLEXPORT *Ptngc_warnmalloc_x(size_t size, char *file, int line); +void DECLSPECDLLEXPORT *Ptngc_warnmalloc_x(const size_t size, char *file, const int line); #define warnmalloc(size) Ptngc_warnmalloc_x(size,__FILE__,__LINE__) -void DECLSPECDLLEXPORT *Ptngc_warnrealloc_x(void *old, size_t size, char *file, int line); +void DECLSPECDLLEXPORT *Ptngc_warnrealloc_x(void *old, const size_t size, char *file, const int line); #define warnrealloc(old,size) Ptngc_warnrealloc_x(old,size,__FILE__,__LINE__) diff --git a/src/external/tng_io/include/compression/widemuldiv.h b/src/external/tng_io/include/compression/widemuldiv.h index 8ca24eee6b..dfa905be4e 100644 --- a/src/external/tng_io/include/compression/widemuldiv.h +++ b/src/external/tng_io/include/compression/widemuldiv.h @@ -12,20 +12,13 @@ #ifndef WIDEMULDIV_H #define WIDEMULDIV_H -/* Multiply two 32 bit unsigned integers returning a 64 bit unsigned value (in two integers) */ -void Ptngc_widemul(unsigned int i1, unsigned int i2, unsigned int *ohi, unsigned int *olo); - -/* Divide a 64 bit unsigned value in hi:lo with the 32 bit value i and - return the result in result and the remainder in remainder */ -void Ptngc_widediv(unsigned int hi, unsigned int lo, unsigned int i, unsigned int *result, unsigned int *remainder); - /* Add a unsigned int to a largeint. */ -void Ptngc_largeint_add(unsigned int v1, unsigned int *largeint, int n); +void Ptngc_largeint_add(const unsigned int v1, unsigned int *largeint, const int n); /* Multiply v1 with largeint_in and return result in largeint_out */ -void Ptngc_largeint_mul(unsigned int v1, unsigned int *largeint_in, unsigned int *largeint_out, int n); +void Ptngc_largeint_mul(const unsigned int v1, unsigned int *largeint_in, unsigned int *largeint_out, const int n); /* Return the remainder from dividing largeint_in with v1. Result of the division is returned in largeint_out */ -unsigned int Ptngc_largeint_div(unsigned int v1, unsigned int *largeint_in, unsigned int *largeint_out, int n); +unsigned int Ptngc_largeint_div(const unsigned int v1, unsigned int *largeint_in, unsigned int *largeint_out, const int n); #endif diff --git a/src/external/tng_io/include/tng/tng_io.h b/src/external/tng_io/include/tng/tng_io.h index c607aad2c5..668acbea7b 100644 --- a/src/external/tng_io/include/tng/tng_io.h +++ b/src/external/tng_io/include/tng/tng_io.h @@ -76,6 +76,13 @@ * * Revisions * + * v. 1.7 - Fifth stable release of the API + * + * - Added function tng_util_num_frames_with_data_of_block_id_get(). + * - Merged some functions and data structures + * to make less difference between data blocks. + * - Bugs fixed + * * v. 1.6 - Fourth stable release of the API. * * - Removed OpenMP option when building. @@ -331,6 +338,7 @@ typedef unsigned __int64 uint64_t; #ifndef PRId64 # define PRId64 __PRI64_PREFIX "d" #endif + #ifndef PRIu64 # define PRIu64 __PRI64_PREFIX "u" #endif @@ -345,12 +353,6 @@ typedef unsigned __int64 uint64_t; #endif /* win32... */ #endif /* not defined USE_WINDOWS */ -#ifdef USE_WINDOWS -#define TNG_PRIsize "Iu" -#else -#define TNG_PRIsize "zu" -#endif - #ifndef DECLSPECDLLEXPORT #ifdef USE_WINDOWS #define DECLSPECDLLEXPORT __declspec(dllexport) @@ -638,7 +640,7 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_destroy * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_trajectory_init_from_src - (tng_trajectory_t src, tng_trajectory_t *dest_p); + (const tng_trajectory_t src, tng_trajectory_t *dest_p); /** * @brief Get the name of the input file. @@ -670,7 +672,7 @@ tng_function_status DECLSPECDLLEXPORT tng_input_file_get * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_input_file_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char *file_name); /** @@ -703,7 +705,7 @@ tng_function_status DECLSPECDLLEXPORT tng_output_file_get * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_output_file_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char *file_name); /** @@ -719,7 +721,7 @@ tng_function_status DECLSPECDLLEXPORT tng_output_file_set * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_output_append_file_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char *file_name); /** @@ -750,7 +752,7 @@ tng_function_status DECLSPECDLLEXPORT tng_output_file_endianness_get * could not be set. */ tng_function_status DECLSPECDLLEXPORT tng_output_file_endianness_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const tng_file_endianness endianness); /** @@ -783,7 +785,7 @@ tng_function_status DECLSPECDLLEXPORT tng_first_program_name_get * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_first_program_name_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char *new_name); /** @@ -816,7 +818,7 @@ tng_function_status DECLSPECDLLEXPORT tng_last_program_name_get * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_last_program_name_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char *new_name); /** @@ -849,7 +851,7 @@ tng_function_status DECLSPECDLLEXPORT tng_first_user_name_get * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_first_user_name_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char *new_name); /** @@ -882,7 +884,7 @@ tng_function_status DECLSPECDLLEXPORT tng_last_user_name_get * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_last_user_name_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char *new_name); /** @@ -915,7 +917,7 @@ tng_function_status DECLSPECDLLEXPORT tng_first_computer_name_get * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_first_computer_name_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char *new_name); /** @@ -948,7 +950,7 @@ tng_function_status DECLSPECDLLEXPORT tng_last_computer_name_get * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_last_computer_name_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char *new_name); /** @@ -981,7 +983,7 @@ tng_function_status DECLSPECDLLEXPORT tng_first_signature_get * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_first_signature_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char *signature); /** @@ -1014,7 +1016,7 @@ tng_function_status DECLSPECDLLEXPORT tng_last_signature_get * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_last_signature_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char *signature); /** @@ -1047,7 +1049,7 @@ tng_function_status DECLSPECDLLEXPORT tng_forcefield_name_get * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_forcefield_name_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char *new_name); /** @@ -1073,7 +1075,7 @@ tng_function_status DECLSPECDLLEXPORT tng_medium_stride_length_get * has occurred. */ tng_function_status DECLSPECDLLEXPORT tng_medium_stride_length_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t len); /** @@ -1099,7 +1101,7 @@ tng_function_status DECLSPECDLLEXPORT tng_long_stride_length_get * has occurred. */ tng_function_status DECLSPECDLLEXPORT tng_long_stride_length_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t len); /** @@ -1126,7 +1128,7 @@ tng_function_status DECLSPECDLLEXPORT tng_time_per_frame_get * has occurred. */ tng_function_status DECLSPECDLLEXPORT tng_time_per_frame_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const double time); /** @@ -1185,7 +1187,7 @@ tng_function_status DECLSPECDLLEXPORT tng_compression_precision_get * @return TNG_SUCCESS (0) if successful. */ tng_function_status DECLSPECDLLEXPORT tng_compression_precision_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const double precision); /** @@ -1200,7 +1202,7 @@ tng_function_status DECLSPECDLLEXPORT tng_compression_precision_set * @return TNG_SUCCESS (0) if successful. */ tng_function_status DECLSPECDLLEXPORT tng_implicit_num_particles_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t n); /** @@ -1376,7 +1378,7 @@ tng_function_status DECLSPECDLLEXPORT tng_current_frame_set_get * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_frame_set_nr_find - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t nr); /** @@ -1392,7 +1394,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_nr_find * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_frame_set_of_frame_find - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame); /** @@ -1478,7 +1480,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_free(const tng_trajectory_t t */ tng_function_status DECLSPECDLLEXPORT tng_molecule_init (const tng_trajectory_t tng_data, - tng_molecule_t molecule); + const tng_molecule_t molecule); /** * @brief Clean up a molecule container. @@ -1491,7 +1493,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_init */ tng_function_status DECLSPECDLLEXPORT tng_molecule_destroy (const tng_trajectory_t tng_data, - tng_molecule_t molecule); + const tng_molecule_t molecule); /** * @brief Add a molecule to the trajectory. @@ -1506,7 +1508,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_destroy * not be set properly or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_molecule_add - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char *name, tng_molecule_t *molecule); @@ -1524,7 +1526,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_add * not be set properly or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_molecule_w_id_add - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char *name, const int64_t id, tng_molecule_t *molecule); @@ -1540,7 +1542,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_w_id_add * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_molecule_existing_add - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, tng_molecule_t *molecule); /** @@ -1576,8 +1578,8 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_name_get * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_molecule_name_set - (tng_trajectory_t tng_data, - tng_molecule_t molecule, + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, const char *new_name); /** @@ -1608,8 +1610,8 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_get * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_set - (tng_trajectory_t tng_data, - tng_molecule_t molecule, + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, const int64_t cnt); /** @@ -1630,9 +1632,9 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_set * be found. */ tng_function_status DECLSPECDLLEXPORT tng_molecule_find - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char *name, - int64_t id, + const int64_t id, tng_molecule_t *molecule); /** @@ -1647,8 +1649,8 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_find * molecule is not found. */ tng_function_status DECLSPECDLLEXPORT tng_molecule_of_index_get - (tng_trajectory_t tng_data, - int64_t index, + (const tng_trajectory_t tng_data, + const int64_t index, tng_molecule_t *molecule); /** @@ -1665,8 +1667,8 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_of_index_get * @return TNG_SUCCESS(0) if the copying is successful, TNG_FAILURE if a minor * error has occured or TNG_CRITICAL(2) if a major error has occured. */ -tng_function_status DECLSPECDLLEXPORT tng_molecule_system_copy(tng_trajectory_t tng_data_src, - tng_trajectory_t tng_data_dest); +tng_function_status DECLSPECDLLEXPORT tng_molecule_system_copy(const tng_trajectory_t tng_data_src, + const tng_trajectory_t tng_data_dest); /** * @brief Get the number of chains in a molecule. @@ -1695,9 +1697,9 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_num_chains_get * chain is not found. */ tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_of_index_get - (tng_trajectory_t tng_data, - tng_molecule_t molecule, - int64_t index, + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, + const int64_t index, tng_chain_t *chain); /** @@ -1783,10 +1785,10 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_atom_of_index_get * be found. */ tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_find - (tng_trajectory_t tng_data, - tng_molecule_t molecule, + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, const char *name, - int64_t id, + const int64_t id, tng_chain_t *chain); /** @@ -1803,8 +1805,8 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_find * not be set properly or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_add - (tng_trajectory_t tng_data, - tng_molecule_t molecule, + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, const char *name, tng_chain_t *chain); @@ -1823,8 +1825,8 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_add * not be set properly or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_w_id_add - (tng_trajectory_t tng_data, - tng_molecule_t molecule, + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, const char *name, const int64_t id, tng_chain_t *chain); @@ -1843,7 +1845,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_w_id_add */ tng_function_status DECLSPECDLLEXPORT tng_molecule_bond_add (const tng_trajectory_t tng_data, - tng_molecule_t molecule, + const tng_molecule_t molecule, const int64_t from_atom_id, const int64_t to_atom_id, tng_bond_t *bond); @@ -1865,10 +1867,10 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_bond_add * be found. */ tng_function_status DECLSPECDLLEXPORT tng_molecule_atom_find - (tng_trajectory_t tng_data, - tng_molecule_t molecule, + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, const char *name, - int64_t id, + const int64_t id, tng_atom_t *atom); /** @@ -1902,8 +1904,8 @@ tng_function_status DECLSPECDLLEXPORT tng_chain_name_get * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_chain_name_set - (tng_trajectory_t tng_data, - tng_chain_t chain, + (const tng_trajectory_t tng_data, + const tng_chain_t chain, const char *new_name); /** @@ -1955,10 +1957,10 @@ tng_function_status DECLSPECDLLEXPORT tng_chain_residue_of_index_get * be found. */ tng_function_status DECLSPECDLLEXPORT tng_chain_residue_find - (tng_trajectory_t tng_data, - tng_chain_t chain, + (const tng_trajectory_t tng_data, + const tng_chain_t chain, const char *name, - int64_t id, + const int64_t id, tng_residue_t *residue); /** @@ -1975,8 +1977,8 @@ tng_function_status DECLSPECDLLEXPORT tng_chain_residue_find * not be set properly or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_chain_residue_add - (tng_trajectory_t tng_data, - tng_chain_t chain, + (const tng_trajectory_t tng_data, + const tng_chain_t chain, const char *name, tng_residue_t *residue); @@ -1995,8 +1997,8 @@ tng_function_status DECLSPECDLLEXPORT tng_chain_residue_add * not be set properly or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_chain_residue_w_id_add - (tng_trajectory_t tng_data, - tng_chain_t chain, + (const tng_trajectory_t tng_data, + const tng_chain_t chain, const char *name, const int64_t id, tng_residue_t *residue); @@ -2034,8 +2036,8 @@ tng_function_status DECLSPECDLLEXPORT tng_residue_name_get * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_residue_name_set - (tng_trajectory_t tng_data, - tng_residue_t residue, + (const tng_trajectory_t tng_data, + const tng_residue_t residue, const char *new_name); /** @@ -2087,8 +2089,8 @@ tng_function_status DECLSPECDLLEXPORT tng_residue_atom_of_index_get * not be set properly or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_residue_atom_add - (tng_trajectory_t tng_data, - tng_residue_t residue, + (const tng_trajectory_t tng_data, + const tng_residue_t residue, const char *atom_name, const char *atom_type, tng_atom_t *atom); @@ -2111,8 +2113,8 @@ tng_function_status DECLSPECDLLEXPORT tng_residue_atom_add * not be set properly or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_residue_atom_w_id_add - (tng_trajectory_t tng_data, - tng_residue_t residue, + (const tng_trajectory_t tng_data, + const tng_residue_t residue, const char *atom_name, const char *atom_type, const int64_t id, @@ -2163,8 +2165,8 @@ tng_function_status DECLSPECDLLEXPORT tng_atom_name_get * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_atom_name_set - (tng_trajectory_t tng_data, - tng_atom_t atom, + (const tng_trajectory_t tng_data, + const tng_atom_t atom, const char *new_name); /** @@ -2200,8 +2202,8 @@ tng_function_status DECLSPECDLLEXPORT tng_atom_type_get * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_atom_type_set - (tng_trajectory_t tng_data, - tng_atom_t atom, + (const tng_trajectory_t tng_data, + const tng_atom_t atom, const char *new_type); /** @@ -2222,7 +2224,7 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_name_of_particle_nr_get (const tng_trajectory_t tng_data, const int64_t nr, char *name, - int max_len); + const int max_len); /** * @brief Get the molecule id of real particle number (number in mol system). @@ -2288,7 +2290,7 @@ tng_function_status DECLSPECDLLEXPORT tng_chain_name_of_particle_nr_get (const tng_trajectory_t tng_data, const int64_t nr, char *name, - int max_len); + const int max_len); /** * @brief Get the residue name of real particle number (number in mol system). @@ -2308,7 +2310,7 @@ tng_function_status DECLSPECDLLEXPORT tng_residue_name_of_particle_nr_get (const tng_trajectory_t tng_data, const int64_t nr, char *name, - int max_len); + const int max_len); /** * @brief Get the residue id (local to molecule) of real particle number @@ -2362,7 +2364,7 @@ tng_function_status DECLSPECDLLEXPORT tng_atom_name_of_particle_nr_get (const tng_trajectory_t tng_data, const int64_t nr, char *name, - int max_len); + const int max_len); /** * @brief Get the atom type of real particle number (number in mol system). @@ -2382,7 +2384,7 @@ tng_function_status DECLSPECDLLEXPORT tng_atom_type_of_particle_nr_get (const tng_trajectory_t tng_data, const int64_t nr, char *type, - int max_len); + const int max_len); /** * @brief Add a particle mapping table. @@ -2406,7 +2408,7 @@ tng_function_status DECLSPECDLLEXPORT tng_atom_type_of_particle_nr_get * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_particle_mapping_add - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t num_first_particle, const int64_t n_particles, const int64_t *mapping_table); @@ -2422,7 +2424,7 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_mapping_add * @return TNG_SUCCESS (0) if successful. */ tng_function_status DECLSPECDLLEXPORT tng_frame_set_particle_mapping_free - (tng_trajectory_t tng_data); + (const tng_trajectory_t tng_data); /** * @brief Read the header blocks from the input_file of tng_data. @@ -2441,7 +2443,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_particle_mapping_free * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_file_headers_read - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char hash_mode); /** @@ -2460,7 +2462,7 @@ tng_function_status DECLSPECDLLEXPORT tng_file_headers_read * error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_file_headers_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char hash_mode); /** @@ -2484,8 +2486,8 @@ tng_function_status DECLSPECDLLEXPORT tng_file_headers_write * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_block_read_next - (tng_trajectory_t tng_data, - tng_gen_block_t block_data, + (const tng_trajectory_t tng_data, + const tng_gen_block_t block_data, const char hash_mode); /** @@ -2501,7 +2503,7 @@ tng_function_status DECLSPECDLLEXPORT tng_block_read_next * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char hash_mode); /** @@ -2521,7 +2523,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_current_only_data_from_block_id - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char hash_mode, const int64_t block_id); @@ -2541,7 +2543,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_current_only_data_from_ * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_next - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char hash_mode); /** @@ -2561,7 +2563,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_next * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_next_only_data_from_block_id - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char hash_mode, const int64_t block_id); @@ -2580,7 +2582,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_next_only_data_from_blo * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_frame_set_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char hash_mode); /** @@ -2601,7 +2603,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_write * 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 tng_trajectory_t tng_data, const char hash_mode); /** @@ -2620,7 +2622,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_premature_write * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_frame_set_new - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t first_frame, const int64_t n_frames); @@ -2642,7 +2644,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_new * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_frame_set_with_time_new - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t first_frame, const int64_t n_frames, const double first_frame_time); @@ -2659,7 +2661,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_with_time_new * @return TNG_SUCCESS (0) if successful. */ tng_function_status DECLSPECDLLEXPORT tng_frame_set_first_frame_time_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const double first_frame_time); /** @@ -2708,7 +2710,7 @@ tng_function_status DECLSPECDLLEXPORT tng_first_frame_nr_of_next_frame_set_get * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_data_block_add - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t id, const char *block_name, const char datatype, @@ -2753,7 +2755,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_block_add * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_particle_data_block_add - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t id, const char *block_name, const char datatype, @@ -2781,10 +2783,10 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_block_add * TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_data_block_name_get - (tng_trajectory_t tng_data, - int64_t block_id, + (const tng_trajectory_t tng_data, + const int64_t block_id, char *name, - int max_len); + const int max_len); /** @brief Get the dependency of a data block of a specific ID. * @param tng_data is the trajectory data container. @@ -2803,7 +2805,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_block_name_get */ tng_function_status DECLSPECDLLEXPORT tng_data_block_dependency_get (const tng_trajectory_t tng_data, - int64_t block_id, + const int64_t block_id, int *block_dependency); /** @brief Get the number of values per frame of a data block of a specific ID. @@ -2820,7 +2822,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_block_dependency_get */ tng_function_status DECLSPECDLLEXPORT tng_data_block_num_values_per_frame_get (const tng_trajectory_t tng_data, - int64_t block_id, + const int64_t block_id, int64_t *n_values_per_frame); /** @@ -2844,7 +2846,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_block_num_values_per_frame_get * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_frame_data_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const int64_t block_id, const void *values, @@ -2878,7 +2880,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_data_write * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const int64_t block_id, const int64_t val_first_particle, @@ -2893,6 +2895,9 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write * @param n_frames is the number of frames in the data array. * @param n_values_per_frame is the number of values per frame in the data array. * @param type is the data type of the data in the array (e.g. int/float/char). + * @details This function should not be used. The data_values union is obsolete. + * This function also causes memory leaks, but its signature cannot be changed + * without disturbing the API. * @return TNG_SUCCESS (0) if successful. */ tng_function_status DECLSPECDLLEXPORT tng_data_values_free @@ -2910,6 +2915,9 @@ tng_function_status DECLSPECDLLEXPORT tng_data_values_free * @param n_particles is the number of particles in the data array. * @param n_values_per_frame is the number of values per frame in the data array. * @param type is the data type of the data in the array (e.g. int/float/char). + * @details This function should not be used. The data_values union is obsolete. + * This function also causes memory leaks, but its signature cannot be changed + * without disturbing the API. * @return TNG_SUCCESS (0) if successful. */ tng_function_status DECLSPECDLLEXPORT tng_particle_data_values_free @@ -2949,7 +2957,7 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_values_free * @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_data_get(tng_trajectory_t tng_data, +tng_function_status DECLSPECDLLEXPORT tng_data_get(const tng_trajectory_t tng_data, const int64_t block_id, union data_values ***values, int64_t *n_frames, @@ -2987,7 +2995,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get(tng_trajectory_t tng_data, * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_data_vector_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t block_id, void **values, int64_t *n_frames, @@ -3028,7 +3036,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_vector_get * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_data_interval_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t block_id, const int64_t start_frame_nr, const int64_t end_frame_nr, @@ -3073,7 +3081,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_interval_get * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_data_vector_interval_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t block_id, const int64_t start_frame_nr, const int64_t end_frame_nr, @@ -3120,7 +3128,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_vector_interval_get * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_particle_data_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t block_id, union data_values ****values, int64_t *n_frames, @@ -3165,7 +3173,7 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_get * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t block_id, void **values, int64_t *n_frames, @@ -3216,7 +3224,7 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_get * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t block_id, const int64_t start_frame_nr, const int64_t end_frame_nr, @@ -3270,7 +3278,7 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get * has occurred or TNG_CRITICAL (2) if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_interval_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t block_id, const int64_t start_frame_nr, const int64_t end_frame_nr, @@ -3366,7 +3374,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_close * minor error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_time_of_frame_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, double *time); @@ -3384,7 +3392,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_time_of_frame_get * @return TNG_SUCCESS (0) if successful. */ /*tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_molecules_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, int64_t *n_mols, int64_t **molecule_cnt_list, tng_molecule_t *mols); @@ -3402,14 +3410,14 @@ tng_function_status DECLSPECDLLEXPORT tng_util_time_of_frame_get * has occured or TNG_CRITICAL (2) if a major error has occured. */ /*tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_molecule_add - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char *name, const int64_t cnt, tng_molecule_t *mol); */ /* // tng_function_status DECLSPECDLLEXPORT tng_util_molecule_particles_get -// (tng_trajectory_t tng_data, +// (const tng_trajectory_t tng_data, // const tng_molecule_t mol, // int64_t *n_particles, // char ***names, @@ -3420,7 +3428,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_time_of_frame_get // int64_t **chain_ids); // // tng_function_status DECLSPECDLLEXPORT tng_util_molecule_particles_set -// (tng_trajectory_t tng_data, +// (const tng_trajectory_t tng_data, // tng_molecule_t mol, // const int64_t n_particles, // const char **names, @@ -3451,7 +3459,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_time_of_frame_get * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_pos_read - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, float **positions, int64_t *stride_length); @@ -3476,7 +3484,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_read * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_vel_read - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, float **velocities, int64_t *stride_length); @@ -3501,7 +3509,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_read * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_force_read - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, float **forces, int64_t *stride_length); @@ -3529,7 +3537,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_read * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_read - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, float **box_shape, int64_t *stride_length); @@ -3564,7 +3572,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_read * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t block_id, void **values, char *data_type, @@ -3600,7 +3608,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_non_particle_data_next_frame_read - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t block_id, void **values, char *data_type, @@ -3632,7 +3640,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_non_particle_data_next_frame_read * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_pos_read_range - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t first_frame, const int64_t last_frame, float **positions, @@ -3663,7 +3671,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_read_range * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_vel_read_range - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t first_frame, const int64_t last_frame, float **velocities, @@ -3694,7 +3702,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_read_range * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_force_read_range - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t first_frame, const int64_t last_frame, float **forces, @@ -3731,7 +3739,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_read_range * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_read_range - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t first_frame, const int64_t last_frame, float **box_shape, @@ -3766,7 +3774,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_read_range * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i, const int64_t n_values_per_frame, const int64_t block_id, @@ -3804,7 +3812,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_set * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_double_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i, const int64_t n_values_per_frame, const int64_t block_id, @@ -3841,7 +3849,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_double_set * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_frequency_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i, const int64_t n_values_per_frame, const int64_t block_id, @@ -3865,7 +3873,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_frequency_set * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_interval_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i); /** @@ -3884,7 +3892,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_interval_set * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_interval_double_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i); /** @@ -3905,7 +3913,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_interval_double_set * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_frequency_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i); /** @@ -3924,7 +3932,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_frequency_set * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_interval_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i); /** @@ -3943,7 +3951,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_interval_set * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_interval_double_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i); /** @@ -3961,7 +3969,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_interval_double_set * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_frequency_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i); /** @@ -3980,7 +3988,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_frequency_set * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_force_write_interval_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i); /** @@ -3999,7 +4007,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_write_interval_set * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_force_write_interval_double_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i); /** @@ -4017,7 +4025,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_write_interval_double_set * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_force_write_frequency_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i); /** @@ -4036,7 +4044,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_write_frequency_set * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_interval_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i); /** @@ -4055,7 +4063,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_interval_set * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_interval_double_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i); /** @@ -4073,13 +4081,14 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_interval_double_s * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_frequency_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i); /** * @brief High-level function for writing data of one frame to a data block. * @param tng_data is the trajectory to use. - * @param frame_nr is the frame number of the data. + * @param frame_nr is the frame number of the data. If frame_nr < 0 the + * data is written as non-trajectory data. * @param values is a 1D array of data to add. The array should be of length * n_particles * n_values_per_frame if writing particle related data, otherwise * it should be n_values_per_frame. @@ -4098,7 +4107,6 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_frequency_set * Only required if the block did not exist, i.e. a new block is created. * @pre \code tng_data != 0 \endcode The trajectory container (tng_data) * must be initialised before using it. - * @pre \code frame_nr >= 0 \endcode The frame number to write must be >= 0. * @pre \code values != 0 \endcode The pointer to the values array must not * be a NULL pointer. * @details n_values_per_frame, block_name, particle_dependency and @@ -4112,7 +4120,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_frequency_set * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const float *values, const int64_t n_values_per_frame, @@ -4125,7 +4133,8 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write * @brief High-level function for writing data of one frame to a double precision * data block. * @param tng_data is the trajectory to use. - * @param frame_nr is the frame number of the data. + * @param frame_nr is the frame number of the data. If frame_nr < 0 the + * data is written as non-trajectory data. * @param values is a 1D array of data to add. The array should be of length * n_particles * n_values_per_frame if writing particle related data, otherwise * it should be n_values_per_frame. @@ -4144,7 +4153,6 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write * Only required if the block did not exist, i.e. a new block is created. * @pre \code tng_data != 0 \endcode The trajectory container (tng_data) * must be initialised before using it. - * @pre \code frame_nr >= 0 \endcode The frame number to write must be >= 0. * @pre \code values != 0 \endcode The pointer to the values array must not * be a NULL pointer. * @details n_values_per_frame, block_name, particle_dependency and @@ -4158,7 +4166,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double *values, const int64_t n_values_per_frame, @@ -4170,12 +4178,12 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write /** * @brief High-level function for adding data to positions data blocks. * @param tng_data is the trajectory to use. - * @param frame_nr is the frame number of the data. + * @param frame_nr is the frame number of the data. If frame_nr < 0 the + * data is written as non-trajectory data. * @param positions is a 1D array of data to add. The array should be of length * n_particles * 3. * @pre \code tng_data != 0 \endcode The trajectory container (tng_data) * must be initialised before using it. - * @pre \code frame_nr >= 0 \endcode The frame number to write must be >= 0. * @pre \code positions != 0 \endcode The pointer to the positions array must not * be a NULL pointer. * @details This function uses tng_util_generic_write() and will @@ -4189,7 +4197,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_pos_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const float *positions); @@ -4197,12 +4205,12 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_write * @brief High-level function for adding data to positions data blocks at double * precision. * @param tng_data is the trajectory to use. - * @param frame_nr is the frame number of the data. + * @param frame_nr is the frame number of the data. If frame_nr < 0 the + * data is written as non-trajectory data. * @param positions is a 1D array of data to add. The array should be of length * n_particles * 3. * @pre \code tng_data != 0 \endcode The trajectory container (tng_data) * must be initialised before using it. - * @pre \code frame_nr >= 0 \endcode The frame number to write must be >= 0. * @pre \code positions != 0 \endcode The pointer to the positions array must not * be a NULL pointer. * @details This function uses tng_util_generic_write() and will @@ -4216,19 +4224,19 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_pos_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double *positions); /** * @brief High-level function for adding data to velocities data blocks. * @param tng_data is the trajectory to use. - * @param frame_nr is the frame number of the data. + * @param frame_nr is the frame number of the data. If frame_nr < 0 the + * data is written as non-trajectory data. * @param velocities is a 1D array of data to add. The array should be of length * n_particles * 3. * @pre \code tng_data != 0 \endcode The trajectory container (tng_data) * must be initialised before using it. - * @pre \code frame_nr >= 0 \endcode The frame number to write must be >= 0. * @pre \code velocities != 0 \endcode The pointer to the velocities array must not * be a NULL pointer. * @details This function uses tng_util_generic_write() and will @@ -4242,7 +4250,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_double_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_vel_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const float *velocities); @@ -4250,12 +4258,12 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_write * @brief High-level function for adding data to velocities data blocks at double * precision. * @param tng_data is the trajectory to use. - * @param frame_nr is the frame number of the data. + * @param frame_nr is the frame number of the data. If frame_nr < 0 the + * data is written as non-trajectory data. * @param velocities is a 1D array of data to add. The array should be of length * n_particles * 3. * @pre \code tng_data != 0 \endcode The trajectory container (tng_data) * must be initialised before using it. - * @pre \code frame_nr >= 0 \endcode The frame number to write must be >= 0. * @pre \code velocities != 0 \endcode The pointer to the velocities array must not * be a NULL pointer. * @details This function uses tng_util_generic_write() and will @@ -4269,19 +4277,19 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_vel_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double *velocities); /** * @brief High-level function for adding data to forces data blocks. * @param tng_data is the trajectory to use. - * @param frame_nr is the frame number of the data. + * @param frame_nr is the frame number of the data. If frame_nr < 0 the + * data is written as non-trajectory data. * @param forces is a 1D array of data to add. The array should be of length * n_particles * 3. * @pre \code tng_data != 0 \endcode The trajectory container (tng_data) * must be initialised before using it. - * @pre \code frame_nr >= 0 \endcode The frame number to write must be >= 0. * @pre \code forces != 0 \endcode The pointer to the forces array must not * be a NULL pointer. * @details This function uses tng_util_generic_write() and will @@ -4295,7 +4303,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_double_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_force_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const float *forces); @@ -4303,12 +4311,12 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_write * @brief High-level function for adding data to forces data blocks at double * precision. * @param tng_data is the trajectory to use. - * @param frame_nr is the frame number of the data. + * @param frame_nr is the frame number of the data. If frame_nr < 0 the + * data is written as non-trajectory data. * @param forces is a 1D array of data to add. The array should be of length * n_particles * 3. * @pre \code tng_data != 0 \endcode The trajectory container (tng_data) * must be initialised before using it. - * @pre \code frame_nr >= 0 \endcode The frame number to write must be >= 0. * @pre \code forces != 0 \endcode The pointer to the forces array must not * be a NULL pointer. * @details This function uses tng_util_generic_write() and will @@ -4322,18 +4330,18 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_force_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double *forces); /** * @brief High-level function for adding data to box shape data blocks. * @param tng_data is the trajectory to use. - * @param frame_nr is the frame number of the data. + * @param frame_nr is the frame number of the data. If frame_nr < 0 the + * data is written as non-trajectory data. * @param box_shape is a 1D array of data to add. The array should be of length 9. * @pre \code tng_data != 0 \endcode The trajectory container (tng_data) * must be initialised before using it. - * @pre \code frame_nr >= 0 \endcode The frame number to write must be >= 0. * @pre \code box_shape != 0 \endcode The pointer to the box_shape array must not * be a NULL pointer. * @details This function uses tng_util_generic_write() and will @@ -4347,7 +4355,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_double_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const float *box_shape); @@ -4355,11 +4363,11 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write * @brief High-level function for adding data to box shape data blocks at double * precision. * @param tng_data is the trajectory to use. - * @param frame_nr is the frame number of the data. + * @param frame_nr is the frame number of the data. If frame_nr < 0 the + * data is written as non-trajectory data. * @param box_shape is a 1D array of data to add. The array should be of length 9. * @pre \code tng_data != 0 \endcode The trajectory container (tng_data) * must be initialised before using it. - * @pre \code frame_nr >= 0 \endcode The frame number to write must be >= 0. * @pre \code box_shape != 0 \endcode The pointer to the box_shape array must not * be a NULL pointer. * @details This function uses tng_util_generic_write() and will @@ -4373,7 +4381,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double *box_shape); @@ -4417,7 +4425,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_double_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_generic_with_time_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const float *values, @@ -4467,7 +4475,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_with_time_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_generic_with_time_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const double *values, @@ -4503,7 +4511,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_with_time_double_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_pos_with_time_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const float *positions); @@ -4534,7 +4542,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_with_time_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_pos_with_time_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const double *positions); @@ -4565,7 +4573,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_with_time_double_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_vel_with_time_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const float *velocities); @@ -4596,7 +4604,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_with_time_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_vel_with_time_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const double *velocities); @@ -4627,7 +4635,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_with_time_double_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_force_with_time_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const float *forces); @@ -4658,7 +4666,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_with_time_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_force_with_time_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const double *forces); @@ -4688,7 +4696,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_with_time_double_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_with_time_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const float *box_shape); @@ -4718,7 +4726,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_with_time_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_with_time_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const double *box_shape); @@ -4745,7 +4753,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_with_time_double_write * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_frame_current_compression_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t block_id, int64_t *codec_id, double *factor); @@ -4784,7 +4792,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_frame_current_compression_get * has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_data_blocks_find - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, int64_t current_frame, const int64_t n_requested_data_block_ids, const int64_t *requested_data_block_ids, @@ -4850,7 +4858,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_dat */ /* tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_all_data_block_types_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, int64_t *n_data_blocks, int64_t **data_block_ids, char ***data_block_names, @@ -4873,9 +4881,22 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_all_data_block_types_g * if a major error has occured. */ tng_function_status DECLSPECDLLEXPORT tng_util_prepare_append_after_frame - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t prev_frame); + +/** @brief Get the number of frames containing data of a specific type. + * @param tng_data is the trajectory to use. + * @param block_id is the id of the block of the data type. + * @param n_frames is set to the number of frames containing data of + * the requested data type. + * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major + * error has occured. + */ +tng_function_status DECLSPECDLLEXPORT tng_util_num_frames_with_data_of_block_id_get + (const tng_trajectory_t tng_data, + const int64_t block_id, + int64_t *n_frames); /** @} */ /* end of group2 */ diff --git a/src/external/tng_io/include/tng/tng_io_fwd.h b/src/external/tng_io/include/tng/tng_io_fwd.h index 8b63a9a55e..68bcafdea1 100644 --- a/src/external/tng_io/include/tng/tng_io_fwd.h +++ b/src/external/tng_io/include/tng/tng_io_fwd.h @@ -31,9 +31,7 @@ typedef struct tng_gen_block *tng_gen_block_t; typedef struct tng_particle_mapping *tng_particle_mapping_t; /** A pointer to a structure containing frame set information. */ typedef struct tng_trajectory_frame_set *tng_trajectory_frame_set_t; -/** A pointer to a particle data container. */ -typedef struct tng_particle_data *tng_particle_data_t; -/** A pointer to a non-particle data container. */ -typedef struct tng_non_particle_data *tng_non_particle_data_t; +/** A pointer to a data container. */ +typedef struct tng_data *tng_data_t; #endif diff --git a/src/external/tng_io/src/compression/bwlzh.c b/src/external/tng_io/src/compression/bwlzh.c index de009d93f9..f4c0c28e48 100644 --- a/src/external/tng_io/src/compression/bwlzh.c +++ b/src/external/tng_io/src/compression/bwlzh.c @@ -40,13 +40,13 @@ #define PARTIAL_MTF #endif -int bwlzh_get_buflen(int nvals) +int bwlzh_get_buflen(const int nvals) { return 132000+nvals*8+12*((nvals+MAX_VALS_PER_BLOCK)/MAX_VALS_PER_BLOCK); } #ifdef SHOWIT -static void printvals(char *name, unsigned int *vals, int nvals) +static void printvals(const char *name, unsigned int *vals, const int nvals) { int i; int nvalsmax=nvals; @@ -69,10 +69,10 @@ static void printvals(char *name, unsigned int *vals, int nvals) #endif -static void bwlzh_compress_gen(unsigned int *vals, int nvals, +static void bwlzh_compress_gen(unsigned int *vals, const int nvals, unsigned char *output, int *output_len, - int enable_lz77, - int verbose) + const int enable_lz77, + const int verbose) { unsigned int *vals16; int nvals16; @@ -460,35 +460,35 @@ static void bwlzh_compress_gen(unsigned int *vals, int nvals, } -void DECLSPECDLLEXPORT bwlzh_compress(unsigned int *vals, int nvals, +void DECLSPECDLLEXPORT bwlzh_compress(unsigned int *vals, const int nvals, unsigned char *output, int *output_len) { bwlzh_compress_gen(vals,nvals,output,output_len,1,0); } -void DECLSPECDLLEXPORT bwlzh_compress_verbose(unsigned int *vals, int nvals, +void DECLSPECDLLEXPORT bwlzh_compress_verbose(unsigned int *vals, const int nvals, unsigned char *output, int *output_len) { bwlzh_compress_gen(vals,nvals,output,output_len,1,1); } -void DECLSPECDLLEXPORT bwlzh_compress_no_lz77(unsigned int *vals, int nvals, +void DECLSPECDLLEXPORT bwlzh_compress_no_lz77(unsigned int *vals, const int nvals, unsigned char *output, int *output_len) { bwlzh_compress_gen(vals,nvals,output,output_len,0,0); } -void DECLSPECDLLEXPORT bwlzh_compress_no_lz77_verbose(unsigned int *vals, int nvals, +void DECLSPECDLLEXPORT bwlzh_compress_no_lz77_verbose(unsigned int *vals, const int nvals, unsigned char *output, int *output_len) { bwlzh_compress_gen(vals,nvals,output,output_len,0,1); } -static void bwlzh_decompress_gen(unsigned char *input, int nvals, +static void bwlzh_decompress_gen(unsigned char *input, const int nvals, unsigned int *vals, - int verbose) + const int verbose) { unsigned int *vals16; int nvals16; @@ -785,13 +785,13 @@ static void bwlzh_decompress_gen(unsigned char *input, int nvals, } -void DECLSPECDLLEXPORT bwlzh_decompress(unsigned char *input, int nvals, +void DECLSPECDLLEXPORT bwlzh_decompress(unsigned char *input, const int nvals, unsigned int *vals) { bwlzh_decompress_gen(input,nvals,vals,0); } -void DECLSPECDLLEXPORT bwlzh_decompress_verbose(unsigned char *input, int nvals, +void DECLSPECDLLEXPORT bwlzh_decompress_verbose(unsigned char *input, const int nvals, unsigned int *vals) { bwlzh_decompress_gen(input,nvals,vals,1); diff --git a/src/external/tng_io/src/compression/bwt.c b/src/external/tng_io/src/compression/bwt.c index 66d3ecf1de..c5c46dfe38 100644 --- a/src/external/tng_io/src/compression/bwt.c +++ b/src/external/tng_io/src/compression/bwt.c @@ -1,7 +1,7 @@ /* This code is part of the tng compression routines. * - * Written by Daniel Spangberg - * Copyright (c) 2010, 2013, The GROMACS development team. + * Written by Daniel Spangberg and Magnus Lundborg + * Copyright (c) 2010, 2013-2014 The GROMACS development team. * * * This program is free software; you can redistribute it and/or @@ -22,7 +22,7 @@ #define SHOWIT2 #endif -static int compare_index(int i1,int i2,int nvals,unsigned int *vals,unsigned int *nrepeat) +static int compare_index(int i1,int i2, const int nvals, unsigned int *vals, unsigned int *nrepeat) { int i,j; for (i=0; i1) @@ -140,8 +140,8 @@ void Ptngc_bwt_merge_sort_inner(int *indices, int nvals,unsigned int *vals, } /* Burrows-Wheeler transform. */ -void Ptngc_comp_to_bwt(unsigned int *vals, int nvals, - unsigned int *output, int *index) +void Ptngc_comp_to_bwt(unsigned int *vals, const int nvals, + unsigned int *output, int *index) { int i; int *indices=warnmalloc(2*nvals*sizeof *indices); @@ -162,8 +162,9 @@ void Ptngc_comp_to_bwt(unsigned int *vals, int nvals, indices[i]=i; /* Find the length of the initial repeating pattern for the strings. */ /* First mark that the index does not have a found repeating string. */ - for (i=0; ipack_temporary_bits; - unsigned int pack_temporary=coder_inst->pack_temporary; - while (pack_temporary_bits>=8) + while (coder_inst->pack_temporary_bits>=8) { - unsigned int mask=~(0xFFU<<(pack_temporary_bits-8)); - unsigned char out=(unsigned char)(pack_temporary>>(pack_temporary_bits-8)); + unsigned int mask; + unsigned char out; + coder_inst->pack_temporary_bits-=8; + mask=~(0xFFU<<(coder_inst->pack_temporary_bits)); + out=(unsigned char)(coder_inst->pack_temporary>>(coder_inst->pack_temporary_bits)); **output=out; (*output)++; - pack_temporary_bits-=8; - pack_temporary&=mask; + coder_inst->pack_temporary&=mask; } - coder_inst->pack_temporary_bits=pack_temporary_bits; - coder_inst->pack_temporary=pack_temporary; } void DECLSPECDLLEXPORT Ptngc_write_pattern(struct coder *coder_inst, unsigned int pattern, @@ -80,7 +78,7 @@ void DECLSPECDLLEXPORT Ptngc_write_pattern(struct coder *coder_inst, unsigned in /* Write up to 24 bits */ TNG_INLINE void DECLSPECDLLEXPORT Ptngc_writebits(struct coder *coder_inst, - unsigned int value, int nbits, + unsigned int value, const int nbits, unsigned char **output_ptr) { /* Make room for the bits. */ @@ -91,7 +89,7 @@ TNG_INLINE void DECLSPECDLLEXPORT Ptngc_writebits(struct coder *coder_inst, } /* Write up to 32 bits */ -void DECLSPECDLLEXPORT Ptngc_write32bits(struct coder *coder_inst,unsigned int value, +void DECLSPECDLLEXPORT Ptngc_write32bits(struct coder *coder_inst, unsigned int value, int nbits, unsigned char **output_ptr) { unsigned int mask; @@ -102,11 +100,11 @@ void DECLSPECDLLEXPORT Ptngc_write32bits(struct coder *coder_inst,unsigned int v while (nbits>8) { /* Make room for the bits. */ + nbits-=8; coder_inst->pack_temporary<<=8; coder_inst->pack_temporary_bits+=8; - coder_inst->pack_temporary|=(value&mask)>>(nbits-8); + coder_inst->pack_temporary|=(value&mask)>>(nbits); Ptngc_out8bits(coder_inst,output_ptr); - nbits-=8; mask>>=8; } if (nbits) @@ -167,8 +165,8 @@ static int write_stop_bit_code(struct coder *coder_inst, unsigned int s, return 0; } -static int pack_stopbits_item(struct coder *coder_inst,int item, - unsigned char **output, int coding_parameter) +static int pack_stopbits_item(struct coder *coder_inst, const int item, + unsigned char **output, const int coding_parameter) { /* Find this symbol in table. */ int s=0; @@ -180,8 +178,8 @@ static int pack_stopbits_item(struct coder *coder_inst,int item, } static int pack_triplet(struct coder *coder_inst, unsigned int *s, - unsigned char **output, int coding_parameter, - unsigned int max_base, int maxbits) + unsigned char **output, const int coding_parameter, + const unsigned int max_base, const int maxbits) { /* Determine base for this triplet. */ unsigned int min_base=1U<pack_temporary_bits>0) @@ -221,8 +219,8 @@ void DECLSPECDLLEXPORT Ptngc_pack_flush(struct coder *coder_inst,unsigned char * } unsigned char DECLSPECDLLEXPORT *Ptngc_pack_array(struct coder *coder_inst, - int *input, int *length, int coding, - int coding_parameter, int natoms, int speed) + int *input, int *length, const int coding, + const int coding_parameter, const int natoms, const int speed) { if ((coding==TNG_COMPRESS_ALGO_BWLZH1) || (coding==TNG_COMPRESS_ALGO_BWLZH2)) { @@ -246,7 +244,6 @@ unsigned char DECLSPECDLLEXPORT *Ptngc_pack_array(struct coder *coder_inst, { int item=input[k*3*natoms+i*3+j]; pval[cnt++]=(unsigned int)(item+most_negative); - } if (speed>=5) bwlzh_compress(pval,n,output+4,length); @@ -340,7 +337,7 @@ unsigned char DECLSPECDLLEXPORT *Ptngc_pack_array(struct coder *coder_inst, static int unpack_array_stop_bits(struct coder *coder_inst, unsigned char *packed,int *output, - int length, int coding_parameter) + const int length, const int coding_parameter) { int i,j; unsigned int extract_mask=0x80; @@ -395,7 +392,7 @@ static int unpack_array_stop_bits(struct coder *coder_inst, static int unpack_array_triplet(struct coder *coder_inst, unsigned char *packed, int *output, - int length, int coding_parameter) + int length, const int coding_parameter) { int i,j; unsigned int extract_mask=0x80; @@ -469,7 +466,7 @@ static int unpack_array_triplet(struct coder *coder_inst, static int unpack_array_bwlzh(struct coder *coder_inst, unsigned char *packed, int *output, - int length, int natoms) + const int length, const int natoms) { int i,j,k,n=length; unsigned int *pval=warnmalloc(n*sizeof *pval); @@ -494,8 +491,8 @@ static int unpack_array_bwlzh(struct coder *coder_inst, int DECLSPECDLLEXPORT Ptngc_unpack_array(struct coder *coder_inst, unsigned char *packed, int *output, - int length, int coding, int coding_parameter, - int natoms) + const int length, const int coding, const int coding_parameter, + const int natoms) { if ((coding==TNG_COMPRESS_ALGO_STOPBIT) || (coding==TNG_COMPRESS_ALGO_VEL_STOPBIT_INTER)) diff --git a/src/external/tng_io/src/compression/dict.c b/src/external/tng_io/src/compression/dict.c index 24e6ae7cac..7c32d74588 100644 --- a/src/external/tng_io/src/compression/dict.c +++ b/src/external/tng_io/src/compression/dict.c @@ -1,7 +1,7 @@ /* This code is part of the tng compression routines. * - * Written by Daniel Spangberg - * Copyright (c) 2010, 2013, The GROMACS development team. + * Written by Daniel Spangberg and Magnus Lundborg + * Copyright (c) 2010, 2013-2014 The GROMACS development team. * * * This program is free software; you can redistribute it and/or @@ -17,27 +17,29 @@ void Ptngc_comp_canonical_dict(unsigned int *dict, int *ndict) int i; for (i=0; i<0x20004; i++) dict[i]=i; + *ndict=0x20004; } -void Ptngc_comp_make_dict_hist(unsigned int *vals, int nvals, +void Ptngc_comp_make_dict_hist(unsigned int *vals, const int nvals, unsigned int *dict, int *ndict, unsigned int *hist) { int i; int j=0; - for (i=0; i<0x20004; i++) - hist[i]=0; - for (i=0; i<0x20004; i++) - dict[i]=i; + + memset(hist, 0, sizeof(unsigned int)*0x20004); + for (i=0; i +#include #include "../../include/compression/warnmalloc.h" #include "../../include/compression/mtf.h" /* "Partial" MTF. Byte based. */ /* Move to front coding. Acceptable inputs are max 8 bits (0-0xFF) */ -static void comp_conv_to_mtf_byte(unsigned char *vals, int nvals, +static void comp_conv_to_mtf_byte(unsigned char *vals, const int nvals, unsigned char *valsmtf) { int i; @@ -58,13 +59,14 @@ static void comp_conv_to_mtf_byte(unsigned char *vals, int nvals, } } -void Ptngc_comp_conv_to_mtf_partial(unsigned int *vals, int nvals, +void Ptngc_comp_conv_to_mtf_partial(unsigned int *vals, const int nvals, unsigned int *valsmtf) { unsigned char *tmp=warnmalloc(nvals*2); int i, j; - for (i=0; imin_rle) { @@ -36,9 +36,9 @@ static void add_rle(unsigned int *rle, /* Run length encoding. Acceptable inputs are about 16 bits (0-0xFFFF) If input is 0-N output will be be values of 0-(N+2) */ -void Ptngc_comp_conv_to_rle(unsigned int *vals, int nvals, - unsigned int *rle, int *nrle, - int min_rle) +void Ptngc_comp_conv_to_rle(unsigned int *vals, const int nvals, + unsigned int *rle, int *nrle, + const int min_rle) { int i; int j=0; @@ -69,7 +69,7 @@ void Ptngc_comp_conv_to_rle(unsigned int *vals, int nvals, } void Ptngc_comp_conv_from_rle(unsigned int *rle, - unsigned int *vals, int nvals) + unsigned int *vals, const int nvals) { int i=0; int j=0; diff --git a/src/external/tng_io/src/compression/tng_compress.c b/src/external/tng_io/src/compression/tng_compress.c index b39d7220cb..d6497d5612 100644 --- a/src/external/tng_io/src/compression/tng_compress.c +++ b/src/external/tng_io/src/compression/tng_compress.c @@ -28,7 +28,7 @@ #define MAX_FVAL 2147483647. -static int verify_input_data(double *x, int natoms, int nframes, double precision) +static int verify_input_data(double *x, const int natoms, const int nframes, const double precision) { int iframe, i, j; for (iframe=0; iframe #include +#include #include "../../include/compression/tng_compress.h" @@ -31,8 +32,14 @@ #endif /* gcc & x86_64 */ #endif /* TRAJNG X86 GCC INLINE MULDIV */ +#ifdef USE_WINDOWS +#define TNG_INLINE __inline +#else +#define TNG_INLINE inline +#endif + /* Multiply two 32 bit unsigned integers returning a 64 bit unsigned value (in two integers) */ -void Ptngc_widemul(unsigned int i1, unsigned int i2, unsigned int *ohi, unsigned int *olo) +static TNG_INLINE void Ptngc_widemul(unsigned int i1, unsigned int i2, unsigned int *ohi, unsigned int *olo) { #if defined(TRAJNG_X86_GCC_INLINE_MULDIV) __asm__ __volatile__ ("mull %%edx\n\t" @@ -99,7 +106,7 @@ void Ptngc_widemul(unsigned int i1, unsigned int i2, unsigned int *ohi, unsigned /* Divide a 64 bit unsigned value in hi:lo with the 32 bit value i and return the result in result and the remainder in remainder */ -void Ptngc_widediv(unsigned int hi, unsigned int lo, unsigned int i, unsigned int *result, unsigned int *remainder) +static TNG_INLINE void Ptngc_widediv(unsigned int hi, unsigned int lo, const unsigned int i, unsigned int *result, unsigned int *remainder) { #if defined(TRAJNG_X86_GCC_INLINE_MULDIV) __asm__ __volatile__ ("divl %%ecx\n\t" @@ -163,7 +170,7 @@ void Ptngc_widediv(unsigned int hi, unsigned int lo, unsigned int i, unsigned in /* Add a unsigned int to a largeint. j determines which value in the largeint to add v1 to. */ -static void largeint_add_gen(unsigned int v1, unsigned int *largeint, int n, int j) +static TNG_INLINE void largeint_add_gen(const unsigned int v1, unsigned int *largeint, const int n, int j) { /* Add with carry. unsigned ints in C wrap modulo 2**bits when "overflowed". */ unsigned int v2=(v1+largeint[j])&0xFFFFFFFFU; /* Add and cap at 32 bits */ @@ -184,46 +191,50 @@ static void largeint_add_gen(unsigned int v1, unsigned int *largeint, int n, int } /* Add a unsigned int to a largeint. */ -void Ptngc_largeint_add(unsigned int v1, unsigned int *largeint, int n) +void Ptngc_largeint_add(const unsigned int v1, unsigned int *largeint, const int n) { largeint_add_gen(v1,largeint,n,0); } /* Multiply v1 with largeint_in and return result in largeint_out */ -void Ptngc_largeint_mul(unsigned int v1, unsigned int *largeint_in, unsigned int *largeint_out, int n) +void Ptngc_largeint_mul(const unsigned int v1, unsigned int *largeint_in, unsigned int *largeint_out, const int n) { int i; - for (i=0; i64 mul */ largeint_add_gen(lo,largeint_out,n,i); - if (i+164 mul */ + largeint_add_gen(lo,largeint_out,n,i); + } } /* Return the remainder from dividing largeint_in with v1. Result of the division is returned in largeint_out */ -unsigned int Ptngc_largeint_div(unsigned int v1, unsigned int *largeint_in, unsigned int *largeint_out, int n) +unsigned int Ptngc_largeint_div(const unsigned int v1, unsigned int *largeint_in, unsigned int *largeint_out, const int n) { unsigned int result,remainder=0; int i; - unsigned int hi, lo; + unsigned int hi; /* Boot */ hi=0U; i=n; while (i) { - lo=largeint_in[i-1]; - Ptngc_widediv(hi,lo,v1,&result,&remainder); - largeint_out[i-1]=result; - hi=remainder; i--; + Ptngc_widediv(hi,largeint_in[i],v1,&result,&remainder); + largeint_out[i]=result; + hi=remainder; } return remainder; } diff --git a/src/external/tng_io/src/compression/xtc2.c b/src/external/tng_io/src/compression/xtc2.c index bbd45e9dbb..7332f5ffe2 100644 --- a/src/external/tng_io/src/compression/xtc2.c +++ b/src/external/tng_io/src/compression/xtc2.c @@ -1,7 +1,7 @@ /* This code is part of the tng compression routines. * - * Written by Daniel Spangberg - * Copyright (c) 2010, 2013, The GROMACS development team. + * Written by Daniel Spangberg and Magnus Lundborg + * Copyright (c) 2010, 2013-2014 The GROMACS development team. * * * This program is free software; you can redistribute it and/or @@ -26,6 +26,12 @@ /* Generated by gen_magic.py */ #define MAX_MAGIC 92 +#ifdef USE_WINDOWS +#define TNG_INLINE __inline +#else +#define TNG_INLINE inline +#endif + static unsigned int magic[MAX_MAGIC]={ 2U, 3U, 4U, 5U, 6U, 8U, 10U, 12U, @@ -159,20 +165,43 @@ static const double iflipgaincheck=0.89089871814033927; /* 1./(2**(1./6)) */ #define SHOWIT #endif -int Ptngc_magic(unsigned int i) +#ifdef USE_WINDOWS +#define TNG_INLINE __inline +#else +#define TNG_INLINE inline +#endif + +int Ptngc_magic(const unsigned int i) { return magic[i]; } -int Ptngc_find_magic_index(unsigned int maxval) +int Ptngc_find_magic_index(const unsigned int maxval) { - int i=0; + int i; + + if(maxval > magic[MAX_MAGIC/4]) + { + if(maxval > magic[MAX_MAGIC/2]) + { + i = MAX_MAGIC/2 + 1; + } + else + { + i = MAX_MAGIC/4 + 1; + } + } + else + { + i = 0; + } + while (magic[i]<=maxval) i++; return i; } -static unsigned int positive_int(int item) +static TNG_INLINE unsigned int positive_int(const int item) { int s=0; if (item>0) @@ -182,7 +211,7 @@ static unsigned int positive_int(int item) return s; } -static int unpositive_int(int val) +static TNG_INLINE int unpositive_int(const int val) { int s=(val+1)/2; if ((val%2)==0) @@ -233,7 +262,7 @@ static const int seq_instr[MAXINSTR][2]= more efficiently coded with two large instructions. */ }; -static void write_instruction(struct coder *coder,int instr,unsigned char **output_ptr) +static void write_instruction(struct coder *coder, const int instr, unsigned char **output_ptr) { Ptngc_writebits(coder,seq_instr[instr][0],seq_instr[instr][1],output_ptr); #ifdef SHOWIT @@ -359,7 +388,7 @@ static void swap_is_better(int *input, int *minint, int *sum_normal, int *sum_sw *sum_swapped=swapped_max; } -static void swapdecide(struct coder *coder, int *input,int *swapatoms, int *large_index, int *minint, unsigned char **output_ptr) +static void swapdecide(struct coder *coder, int *input, int *swapatoms, int *large_index, int *minint, unsigned char **output_ptr) { int didswap=0; int normal,swapped; @@ -438,23 +467,26 @@ static int compute_magic_bits(int *index) /* Convert a sequence of (hopefully) small positive integers using the base pointed to by index (x base, y base and z base can be different). The largest number of integers supported is 18 (29 to handle/detect overflow) */ -static void trajcoder_base_compress(int *input, int n, int *index, unsigned char *result) +static void trajcoder_base_compress(int *input, const int n, int *index, unsigned char *result) { unsigned int largeint[19]; unsigned int largeint_tmp[19]; - int i,j; - for (i=0; i<19; i++) - largeint[i]=0U; + int i, j; + + memset(largeint, 0U, sizeof(unsigned int) * 19); - for (i=0; i 0) { - if (i!=0) - { - /* We must do the multiplication of the largeint with the integer base */ - Ptngc_largeint_mul(magic[index[i%3]],largeint,largeint_tmp,19); - for (j=0; j<19; j++) - largeint[j]=largeint_tmp[j]; - } + Ptngc_largeint_add(input[0],largeint,19); + } + + for (i=1; imaxint[j]) - maxint[j]=input[i*3+j]; - if (input[i*3+j]maxint[j]) + maxint[j]=input[i*3+j]; + if (input[i*3+j]0) @@ -74,7 +80,7 @@ static unsigned int positive_int(int item) return s; } -static int unpositive_int(int val) +static TNG_INLINE int unpositive_int(const int val) { int s=(val+1)/2; if ((val%2)==0) @@ -153,14 +159,14 @@ static void free_xtc3_context(struct xtc3_context *xtc3_context) } /* Modifies three integer values for better compression of water */ -static void swap_ints(int *in, int *out) +static void swap_ints(const int *in, int *out) { out[0]=in[0]+in[1]; out[1]=-in[1]; out[2]=in[1]+in[2]; } -static void swap_is_better(int *input, int *minint, int *sum_normal, int *sum_swapped) +static void swap_is_better(const int *input, const int *minint, int *sum_normal, int *sum_swapped) { int normal_max=0; int swapped_max=0; @@ -200,7 +206,7 @@ static void allocate_enough_memory(unsigned int **ptr, int *nele, int *nele_allo } static void insert_value_in_array(unsigned int **ptr, int *nele, int *nele_alloc, - unsigned int value, + const unsigned int value, char *arrayname) { #ifndef SHOWIT @@ -266,7 +272,7 @@ static void swapdecide(struct xtc3_context *xtc3_context, int *input,int *swapat /* It is "large" if we have to increase the small index quite a bit. Not so much to be rejected by the not very large check later. */ -static int is_quite_large(int *input, int small_index, int max_large_index) +static int is_quite_large(const int *input, const int small_index, const int max_large_index) { int is=0; int i; @@ -289,7 +295,7 @@ int nbits_sum; int nvalues_sum; #endif -static void insert_batch(int *input_ptr, int ntriplets_left, int *prevcoord, int *encode_ints, int startenc, int *nenc) +static void insert_batch(const int *input_ptr, const int ntriplets_left, const int *prevcoord, int *encode_ints, const int startenc, int *nenc) { int nencode=startenc*3; int tmp_prevcoord[3]; @@ -347,7 +353,7 @@ static void insert_batch(int *input_ptr, int ntriplets_left, int *prevcoord, int *nenc=nencode; } -static void large_instruction_change(struct xtc3_context *xtc3_context, int i) +static void large_instruction_change(struct xtc3_context *xtc3_context, const int i) { /* If the first large is of a different kind than the currently used we must emit an "instruction" to change the large type. */ @@ -369,7 +375,7 @@ static void large_instruction_change(struct xtc3_context *xtc3_context, int i) } static void write_three_large(struct xtc3_context *xtc3_context, - int i) + const int i) { int m; if (xtc3_context->current_large_type==0) @@ -399,7 +405,7 @@ static void write_three_large(struct xtc3_context *xtc3_context, } static void flush_large(struct xtc3_context *xtc3_context, - int n) /* How many to flush. */ + const int n) /* How many to flush. */ { int i; i=0; @@ -464,8 +470,8 @@ static double compute_intlen(unsigned int *ints) return (double)m; } -static void buffer_large(struct xtc3_context *xtc3_context, int *input, int inpdata, - int natoms, int intradelta_ok) +static void buffer_large(struct xtc3_context *xtc3_context, int *input, const int inpdata, + const int natoms, const int intradelta_ok) { unsigned int direct[3], intradelta[3]={0,}, interdelta[3]={0,}; double minlen; @@ -536,7 +542,7 @@ static void buffer_large(struct xtc3_context *xtc3_context, int *input, int inpd xtc3_context->has_large++; } -static void output_int(unsigned char *output,int *outdata, unsigned int n) +static void output_int(unsigned char *output,int *outdata, const unsigned int n) { output[(*outdata)++]=((unsigned int)n)&0xFFU; output[(*outdata)++]=(((unsigned int)n)>>8)&0xFFU; @@ -568,21 +574,21 @@ static void printarray(unsigned int *a, int n, char *name) #define BASEINTERVAL 8 /* How many bytes are needed to store n values in base base */ -static int base_bytes(unsigned int base, int n) +static int base_bytes(const unsigned int base, const int n) { int i,j; unsigned int largeint[MAXMAXBASEVALS+1]; unsigned int largeint_tmp[MAXMAXBASEVALS+1]; int numbytes=0; - for (i=0; i14 bits) we return 0, otherwise 1 */ -static int heuristic_bwlzh(unsigned int *ints, int nints) +static int heuristic_bwlzh(unsigned int *ints, const int nints) { int i,num; num=0; @@ -808,7 +814,7 @@ static int heuristic_bwlzh(unsigned int *ints, int nints) Speed 5 enables the LZ77 component of BWLZH. Speed 6 always tests if BWLZH is better and if it is uses it. This can be very slow. */ -unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int speed) +unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, const int natoms, int speed) { unsigned char *output=NULL; int i,ienc,j; @@ -840,9 +846,8 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp struct xtc3_context xtc3_context; init_xtc3_context(&xtc3_context); - xtc3_context.maxint[0]=xtc3_context.minint[0]=input[0]; - xtc3_context.maxint[1]=xtc3_context.minint[1]=input[1]; - xtc3_context.maxint[2]=xtc3_context.minint[2]=input[2]; + memcpy(xtc3_context.maxint, input, 3*sizeof *xtc3_context.maxint); + memcpy(xtc3_context.minint, input, 3*sizeof *xtc3_context.maxint); /* Values of speed should be sane. */ if (speed<1) @@ -923,6 +928,7 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp #endif /* Initial prevcoord is the minimum integers. */ + memcpy(prevcoord, xtc3_context.minint, 3*sizeof *prevcoord); prevcoord[0]=xtc3_context.minint[0]; prevcoord[1]=xtc3_context.minint[1]; prevcoord[2]=xtc3_context.minint[2]; @@ -1663,7 +1669,7 @@ unsigned char *Ptngc_pack_array_xtc3(int *input, int *length, int natoms, int sp } static void decompress_bwlzh_block(unsigned char **ptr, - int nvals, + const int nvals, unsigned int **vals) { int bwlzh_buf_len=(int)(((unsigned int)(*ptr)[0]) | @@ -1677,7 +1683,7 @@ static void decompress_bwlzh_block(unsigned char **ptr, } static void decompress_base_block(unsigned char **ptr, - int nvals, + const int nvals, unsigned int **vals) { int base_buf_len=(int)(((unsigned int)(*ptr)[0]) | @@ -1694,8 +1700,8 @@ static void unpack_one_large(struct xtc3_context *xtc3_context, int *ilargedir, int *ilargeintra, int *ilargeinter, int *prevcoord, int *minint, int *output, - int outdata, int didswap, - int natoms, int current_large_type) + const int outdata, const int didswap, + const int natoms, const int current_large_type) { int large_ints[3]={0,0,0}; if (current_large_type==0 && xtc3_context->large_direct) @@ -1722,9 +1728,7 @@ static void unpack_one_large(struct xtc3_context *xtc3_context, +output[outdata-natoms*3+2+didswap*3]; (*ilargeinter)+=3; } - prevcoord[0]=large_ints[0]; - prevcoord[1]=large_ints[1]; - prevcoord[2]=large_ints[2]; + memcpy(prevcoord, large_ints, 3*sizeof *prevcoord); output[outdata]=large_ints[0]; output[outdata+1]=large_ints[1]; output[outdata+2]=large_ints[2]; @@ -1734,7 +1738,7 @@ static void unpack_one_large(struct xtc3_context *xtc3_context, } -int Ptngc_unpack_array_xtc3(unsigned char *packed,int *output, int length, int natoms) +int Ptngc_unpack_array_xtc3(unsigned char *packed,int *output, const int length, const int natoms) { int i; int minint[3]; @@ -1833,9 +1837,7 @@ int Ptngc_unpack_array_xtc3(unsigned char *packed,int *output, int length, int n } /* Initial prevcoord is the minimum integers. */ - prevcoord[0]=minint[0]; - prevcoord[1]=minint[1]; - prevcoord[2]=minint[2]; + memcpy(prevcoord, minint, 3*sizeof *prevcoord); while (ntriplets_left>0 && iinstr b ? a : b); -} -*/ -static TNG_INLINE int64_t tng_min_i64(int64_t a, int64_t b) -{ - return (a < b ? a : b); -} - -static TNG_INLINE int64_t tng_max_i64(int64_t a, int64_t b) -{ - return (a > b ? a : b); -} - -/* -static TNG_INLINE float tng_min_f(float a, float b) +static TNG_INLINE size_t tng_min_size(const size_t a, const size_t b) { return (a < b ? a : b); } -static TNG_INLINE float tng_max_f(float a, float b) -{ - return (a > b ? a : b); -} - -static TNG_INLINE double tng_min_d(double a, double b) +static TNG_INLINE int64_t tng_min_i64(const int64_t a, const int64_t b) { return (a < b ? a : b); } -static TNG_INLINE double tng_max_d(double a, double b) +static TNG_INLINE int64_t tng_max_i64(const int64_t a, const int64_t b) { return (a > b ? a : b); } -*/ -/** This function swaps the byte order of a 32 bit numerical variable +/** + * @brief This function swaps the byte order of a 32 bit numerical variable * to big endian. - * It does not only work with integer, but e.g. floats need casting. - * If the byte order is already big endian no change is needed. * @param tng_data is a trajectory data container. * @param v is a pointer to a 32 bit numerical value (float or integer). + * @details The function does not only work with integer, but e.g. floats need casting. + * If the byte order is already big endian no change is needed. * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the current * byte order is not recognised. */ @@ -483,14 +428,15 @@ static tng_function_status tng_swap_byte_order_big_endian_32 } } -/** This function swaps the byte order of a 64 bit numerical variable +/** + * @brief This function swaps the byte order of a 64 bit numerical variable * to big endian. - * It does not only work with integer, but e.g. floats need casting. + * @param tng_data is a trajectory data container. + * @param v is a pointer to a 64 bit numerical value (double or integer). + * @details The function does not only work with integer, but e.g. floats need casting. * The byte order swapping routine can convert four different byte * orders to big endian. * If the byte order is already big endian no change is needed. - * @param tng_data is a trajectory data container. - * @param v is a pointer to a 64 bit numerical value (double or integer). * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the current * byte order is not recognised. */ @@ -537,12 +483,13 @@ static tng_function_status tng_swap_byte_order_big_endian_64 } } -/** This function swaps the byte order of a 32 bit numerical variable +/** + * @brief This function swaps the byte order of a 32 bit numerical variable * to little endian. - * It does not only work with integer, but e.g. floats need casting. - * If the byte order is already little endian no change is needed. * @param tng_data is a trajectory data container. * @param v is a pointer to a 32 bit numerical value (float or integer). + * @details The function does not only work with integer, but e.g. floats need casting. + * If the byte order is already little endian no change is needed. * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the current * byte order is not recognised. */ @@ -573,14 +520,15 @@ static tng_function_status tng_swap_byte_order_little_endian_32 } } -/** This function swaps the byte order of a 64 bit numerical variable +/** + * @brief This function swaps the byte order of a 64 bit numerical variable * to little endian. - * It does not only work with integer, but e.g. floats need casting. + * @param tng_data is a trajectory data container. + * @param v is a pointer to a 64 bit numerical value (double or integer). + * @details The function does not only work with integer, but e.g. floats need casting. * The byte order swapping routine can convert four different byte * orders to little endian. * If the byte order is already little endian no change is needed. - * @param tng_data is a trajectory data container. - * @param v is a pointer to a 64 bit numerical value (double or integer). * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the current * byte order is not recognised. */ @@ -632,12 +580,240 @@ static tng_function_status tng_swap_byte_order_little_endian_64 return(TNG_FAILURE); } } -/** Generate the md5 hash of a block. + +/** + * @brief Read a NULL terminated string from a file. + * @param tng_data is a trajectory data container + * @param str is a pointer to the character string that will + * contain the read string. *str is reallocated in the function + * and must be NULL or pointing at already allocated memory. + * @param hash_mode is an option to decide whether to use the md5 hash or not. + * @param md5_state is a pointer to the current md5 storage, which will be + * appended with str if hash_mode == TNG_USE_HASH. + * @param line_nr is the line number where this function was called, to be + * able to give more useful error messages. + */ +static tng_function_status tng_freadstr(const tng_trajectory_t tng_data, + char **str, + const char hash_mode, + md5_state_t *md5_state, + const int line_nr) +{ + char temp[TNG_MAX_STR_LEN], *temp_alloc; + int c, count = 0; + + do + { + c = fgetc(tng_data->input_file); + + if (c == EOF) + { + /* Clear file error flag and return -1 if EOF is read.*/ + clearerr(tng_data->input_file); + return TNG_FAILURE; + } + else + { + /* Cast c to char */ + temp[count++] = (char) c; + } + } while ((temp[count-1] != '\0') && (count < TNG_MAX_STR_LEN)); + + temp_alloc = realloc(*str, count); + if(!temp_alloc) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", count, + __FILE__, line_nr); + free(*str); + *str = 0; + return TNG_FAILURE; + } + *str = temp_alloc; + + strncpy(*str, temp, count); + + if(hash_mode == TNG_USE_HASH) + { + md5_append(md5_state, (md5_byte_t *)*str, count); + } + + return TNG_SUCCESS; +} + +/** + * @brief Write a NULL terminated string to a file. + * @param tng_data is a trajectory data container + * @param str is a pointer to the character string should be written. + * @param hash_mode is an option to decide whether to use the md5 hash or not. + * @param md5_state is a pointer to the current md5 storage, which will be + * appended with str if hash_mode == TNG_USE_HASH. + * @param line_nr is the line number where this function was called, to be + * able to give more useful error messages. + */ +static TNG_INLINE tng_function_status tng_fwritestr(tng_trajectory_t tng_data, + const char *str, + const char hash_mode, + md5_state_t *md5_state, + const int line_nr) +{ + size_t len; + + len = tng_min_size(strlen(str) + 1, TNG_MAX_STR_LEN); + + if(fwrite(str, len, 1, tng_data->output_file) != 1) + { + fprintf(stderr, "TNG library: Could not write block data. %s: %d\n", __FILE__, line_nr); + return(TNG_CRITICAL); + } + + if(hash_mode == TNG_USE_HASH) + { + md5_append(md5_state, (md5_byte_t *)str, len); + } + + return(TNG_SUCCESS); +} + +/** + * @brief Read a numerical value from file. + * The byte order will be swapped if need be. + * @param tng_data is a trajectory data container + * @param dest is a pointer to where to store the read data. + * @param len is the length (in bytes) of the numerical data type. Should + * be 8 for 64 bit, 4 for 32 bit or 1 for a single byte flag. + * @param hash_mode is an option to decide whether to use the md5 hash or not. + * @param md5_state is a pointer to the current md5 storage, which will be + * appended with str if hash_mode == TNG_USE_HASH. + * @param line_nr is the line number where this function was called, to be + * able to give more useful error messages. + */ +static TNG_INLINE tng_function_status tng_file_input_numerical + (const tng_trajectory_t tng_data, + void *dest, + const size_t len, + const char hash_mode, + md5_state_t *md5_state, + const int line_nr) +{ + if(fread(dest, len, 1, tng_data->input_file) == 0) + { + fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, line_nr); + return(TNG_CRITICAL); + } + if(hash_mode == TNG_USE_HASH) + { + md5_append(md5_state, (md5_byte_t *)dest, len); + } + switch(len) + { + case 8: + if(tng_data->input_endianness_swap_func_64 && + tng_data->input_endianness_swap_func_64(tng_data, dest) != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", + __FILE__, line_nr); + } + break; + case 4: + if(tng_data->input_endianness_swap_func_32 && + tng_data->input_endianness_swap_func_32(tng_data, dest) != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", + __FILE__, line_nr); + } + break; + default: + break; + } + + return(TNG_SUCCESS); +} + +/** + * @brief Write a numerical value to file. + * The byte order will be swapped if need be. + * @param tng_data is a trajectory data container + * @param src is a pointer to the data to write. + * @param len is the length (in bytes) of the numerical data type. Should + * be 8 for 64 bit, 4 for 32 bit or 1 for a single byte flag. + * @param hash_mode is an option to decide whether to use the md5 hash or not. + * @param md5_state is a pointer to the current md5 storage, which will be + * appended with str if hash_mode == TNG_USE_HASH. + * @param line_nr is the line number where this function was called, to be + * able to give more useful error messages. + */ +static TNG_INLINE tng_function_status tng_file_output_numerical + (const tng_trajectory_t tng_data, + const void *src, + const size_t len, + const char hash_mode, + md5_state_t *md5_state, + const int line_nr) +{ + int32_t temp_i32; + int64_t temp_i64; + + switch(len) + { + case 8: + temp_i64 = *((int64_t *)src); + if(tng_data->output_endianness_swap_func_64 && + tng_data->output_endianness_swap_func_64(tng_data, &temp_i64) != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", + __FILE__, line_nr); + } + if(fwrite(&temp_i64, len, 1, tng_data->output_file) != 1) + { + fprintf(stderr, "TNG library: Could not write data. %s: %d\n", __FILE__, line_nr); + return(TNG_CRITICAL); + } + if(hash_mode == TNG_USE_HASH) + { + md5_append(md5_state, (md5_byte_t *)&temp_i64, len); + } + break; + case 4: + temp_i32 = *((int32_t *)src); + if(tng_data->output_endianness_swap_func_32 && + tng_data->output_endianness_swap_func_32(tng_data, &temp_i32) != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", + __FILE__, line_nr); + } + if(fwrite(&temp_i32, len, 1, tng_data->output_file) != 1) + { + fprintf(stderr, "TNG library: Could not write data. %s: %d\n", __FILE__, line_nr); + return(TNG_CRITICAL); + } + if(hash_mode == TNG_USE_HASH) + { + md5_append(md5_state, (md5_byte_t *)&temp_i32, len); + } + break; + default: + if(fwrite(src, len, 1, tng_data->output_file) != 1) + { + fprintf(stderr, "TNG library: Could not write data. %s: %d\n", __FILE__, line_nr); + return(TNG_CRITICAL); + } + if(hash_mode == TNG_USE_HASH) + { + md5_append(md5_state, (md5_byte_t *)src, len); + } + break; + } + + return(TNG_SUCCESS); +} + +/** + * @brief Generate the md5 hash of a block. * The hash is created based on the actual block contents. * @param block is a general block container. * @return TNG_SUCCESS (0) if successful. */ -static tng_function_status tng_block_md5_hash_generate(tng_gen_block_t block) +static tng_function_status tng_block_md5_hash_generate(const tng_gen_block_t block) { md5_state_t md5_state; @@ -649,48 +825,59 @@ static tng_function_status tng_block_md5_hash_generate(tng_gen_block_t block) return(TNG_SUCCESS); } -/** Compare the current block md5 hash (e.g. read from file) with the md5 hash - * calculated from the current contents. - * If the current md5 hash is not set skip the comparison. - * @param block is a general block container. - * @param results If the hashes match results is set to TNG_TRUE, otherwise it is - * set to TNG_FALSE. If the hash was not set results is set to TNG_TRUE. - * @return TNG_SUCCESS (0) if successful or TNG_FAILURE (1) if the hash was not - * set. +/** + * @brief If there is data left in the block read that to append that to the MD5 hash. + * @param tng_data is a trajectory data container. + * @param block is the data block that is being read. + * @param start_pos is the file position where the block started. + * @param md5_state is the md5 to which the md5 of the remaining block + * will be appended. + * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major + * error has occured. */ -static tng_function_status tng_md5_hash_match_verify(tng_gen_block_t block, - tng_bool *results) +static tng_function_status tng_md5_remaining_append(const tng_trajectory_t tng_data, + const tng_gen_block_t block, + const int64_t start_pos, + md5_state_t *md5_state) { - md5_state_t md5_state; - char hash[TNG_MD5_HASH_LEN]; - - TNG_ASSERT(block->block_contents_size > 0, "The block contents size must be > 0"); + int64_t curr_file_pos; + char *temp_data; - *results = TNG_TRUE; - if(strncmp(block->md5_hash, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) == 0) + curr_file_pos = ftello(tng_data->input_file); + if(curr_file_pos < start_pos + block->block_contents_size) { - return(TNG_FAILURE); - } - md5_init(&md5_state); - md5_append(&md5_state, (md5_byte_t *)block->block_contents, - (int)block->block_contents_size); - md5_finish(&md5_state, (md5_byte_t *)hash); - - if(strncmp(block->md5_hash, hash, 16) != 0) - { - *results = TNG_FALSE; + temp_data = malloc(start_pos + block->block_contents_size - curr_file_pos); + if(!temp_data) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", + start_pos + block->block_contents_size - curr_file_pos, __FILE__, __LINE__); + return(TNG_CRITICAL); + } + if(fread(temp_data, start_pos + block->block_contents_size - curr_file_pos, + 1, tng_data->input_file) == 0) + { + fprintf(stderr, "TNG library: Cannot read remaining part of block to generate MD5 sum. %s: %d\n", __FILE__, __LINE__); + free(temp_data); + return(TNG_CRITICAL); + } + md5_append(md5_state, (md5_byte_t *)temp_data, + start_pos + block->block_contents_size - curr_file_pos); + free(temp_data); } return(TNG_SUCCESS); } -/** Open the input file if it is not already opened. +/** + * @brief Open the input file if it is not already opened. * @param tng_data is a trajectory data container. * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major * error has occured. */ -static tng_function_status tng_input_file_init(tng_trajectory_t tng_data) +static tng_function_status tng_input_file_init(const tng_trajectory_t tng_data) { + int64_t file_pos; + if(!tng_data->input_file) { if(!tng_data->input_file_path) @@ -707,15 +894,25 @@ static tng_function_status tng_input_file_init(tng_trajectory_t tng_data) return(TNG_CRITICAL); } } + + if(!tng_data->input_file_len) + { + file_pos = ftello(tng_data->input_file); + fseeko(tng_data->input_file, 0, SEEK_END); + tng_data->input_file_len = ftello(tng_data->input_file); + fseeko(tng_data->input_file, file_pos, SEEK_SET); + } + return(TNG_SUCCESS); } -/** Open the output file if it is not already opened +/** + * @brief Open the output file if it is not already opened * @param tng_data is a trajectory data container. * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major * error has occured. */ -static tng_function_status tng_output_file_init(tng_trajectory_t tng_data) +static tng_function_status tng_output_file_init(const tng_trajectory_t tng_data) { if(!tng_data->output_file) { @@ -738,7 +935,8 @@ static tng_function_status tng_output_file_init(tng_trajectory_t tng_data) return(TNG_SUCCESS); } -/** Setup a file block container. +/** + * @brief Setup a file block container. * @param block_p a pointer to memory to initialise as a file block container. * @details Memory is allocated during initialisation. * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major @@ -751,7 +949,7 @@ static tng_function_status tng_block_init(struct tng_gen_block **block_p) *block_p = malloc(sizeof(struct tng_gen_block)); if(!*block_p) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n", + fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n", sizeof(struct tng_gen_block), __FILE__, __LINE__); return(TNG_CRITICAL); } @@ -760,7 +958,7 @@ static tng_function_status tng_block_init(struct tng_gen_block **block_p) block->id = -1; /* Reset the md5_hash */ - memcpy(block->md5_hash, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", TNG_MD5_HASH_LEN); + memset(block->md5_hash, '\0', TNG_MD5_HASH_LEN); block->name = 0; block->block_version = TNG_API_VERSION; block->header_contents = 0; @@ -810,7 +1008,8 @@ static tng_function_status tng_block_destroy(struct tng_gen_block **block_p) return(TNG_SUCCESS); } -/** Read the header of a data block, regardless of its type +/** + * @brief Read the header of a data block, regardless of its type * @param tng_data is a trajectory data container. * @param block is a general block container. * @return TNG_SUCCESS (0) if successful, TNG_FAILURE(1) if a minor @@ -818,10 +1017,9 @@ static tng_function_status tng_block_destroy(struct tng_gen_block **block_p) * the block) or TNG_CRITICAL (2) if a major error has occured. */ static tng_function_status tng_block_header_read - (tng_trajectory_t tng_data, tng_gen_block_t block) + (const tng_trajectory_t tng_data, const tng_gen_block_t block) { - int len; - int64_t offset = 0; + int64_t start_pos; TNG_ASSERT(block != 0, "TNG library: Trying to read to uninitialized block (NULL pointer)."); @@ -830,6 +1028,8 @@ static tng_function_status tng_block_header_read return(TNG_CRITICAL); } + start_pos = ftello(tng_data->input_file); + /* First read the header size to be able to read the whole header. */ if(fread(&block->header_contents_size, sizeof(block->header_contents_size), 1, tng_data->input_file) == 0) @@ -901,119 +1101,49 @@ static tng_function_status tng_block_header_read } } - if(tng_data->input_endianness_swap_func_64) - { - if(tng_data->input_endianness_swap_func_64(tng_data, - &block->header_contents_size) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - - /* Move the reading position to the beginning of the header. */ - fseeko(tng_data->input_file, -(int64_t)sizeof(block->header_contents_size), - SEEK_CUR); - - /* If there is already memory allocated for the contents free it (we do not - * know if the size is correct). */ - if(block->header_contents) + if(tng_data->input_endianness_swap_func_64 && + tng_data->input_endianness_swap_func_64(tng_data, &block->header_contents_size) != TNG_SUCCESS) { - free(block->header_contents); + fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); } - block->header_contents = malloc(block->header_contents_size); - if(!block->header_contents) + if(tng_file_input_numerical(tng_data, &block->block_contents_size, + sizeof(block->block_contents_size), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - block->header_contents_size, __FILE__, __LINE__); return(TNG_CRITICAL); } - /* Read the whole header into header_contents. This way it can be saved - * even if it cannot be interpreted - * for one reason or another. */ - if(fread(block->header_contents, block->header_contents_size, 1, - tng_data->input_file) == 0) + if(tng_file_input_numerical(tng_data, &block->id, + sizeof(block->id), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot read header. %s: %d\n", __FILE__, __LINE__); return(TNG_CRITICAL); } - /* The header contents size has already been read. Skip ahead. */ - offset = sizeof(block->header_contents_size); - - - /* Copy the respective parameters from the header contents block */ - memcpy(&block->block_contents_size, block->header_contents+offset, - sizeof(block->block_contents_size)); - if(tng_data->input_endianness_swap_func_64) + if(fread(block->md5_hash, TNG_MD5_HASH_LEN, 1, tng_data->input_file) == 0) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &block->block_contents_size) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + fprintf(stderr, "TNG library: Cannot read block header. %s: %d\n", __FILE__, __LINE__); + return(TNG_CRITICAL); } - offset += sizeof(block->block_contents_size); + tng_freadstr(tng_data, &block->name, TNG_SKIP_HASH, 0, __LINE__); - memcpy(&block->id, block->header_contents+offset, sizeof(block->id)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &block->block_version, + sizeof(block->block_version), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &block->id) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(block->id); - - memcpy(block->md5_hash, block->header_contents+offset, TNG_MD5_HASH_LEN); - offset += TNG_MD5_HASH_LEN; + fseeko(tng_data->input_file, start_pos + block->header_contents_size, SEEK_SET); - if(block->name && strcmp(block->name, block->header_contents+offset) != 0) - { - free(block->name); - block->name = 0; - } - len = tng_min_i((int)strlen(block->header_contents+offset) + 1, TNG_MAX_STR_LEN); - if(!block->name) - { - block->name = malloc(len); - if(!block->name) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len, - __FILE__, __LINE__); - return(TNG_CRITICAL); - } - strncpy(block->name, block->header_contents+offset, len); - } - offset += len; + return(TNG_SUCCESS); +} - memcpy(&block->block_version, block->header_contents+offset, - sizeof(block->block_version)); - if(tng_data->input_endianness_swap_func_64) - { - if(tng_data->input_endianness_swap_func_64(tng_data, - &block->block_version) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - - return(TNG_SUCCESS); -} - -/** Write a whole block, both header and contents, regardless of it type +/** + * @brief Write a whole block, both header and contents, regardless of it type * @param tng_data is a trajectory data container. * @param block is a general block container. * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if a minor error @@ -1054,7 +1184,8 @@ static tng_function_status tng_block_header_read // } */ -/** Update the md5 hash of a block already written to the file +/** + * @brief Update the md5 hash of a block already written to the file * @param tng_data is a trajectory data container. * @param block is the block, of which to update the md5 hash. * @param header_start_pos is the file position where the block header starts. @@ -1063,8 +1194,8 @@ static tng_function_status tng_block_header_read * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major * error has occured. */ -static tng_function_status tng_md5_hash_update(tng_trajectory_t tng_data, - tng_gen_block_t block, +static tng_function_status tng_md5_hash_update(const tng_trajectory_t tng_data, + const tng_gen_block_t block, const int64_t header_start_pos, const int64_t contents_start_pos) { @@ -1098,7 +1229,8 @@ static tng_function_status tng_md5_hash_update(tng_trajectory_t tng_data, return(TNG_SUCCESS); } -/** Update the frame set pointers in the file header (general info block), +/** + * @brief Update the frame set pointers in the file header (general info block), * already written to disk * @param tng_data is a trajectory data container. * @param hash_mode specifies whether to update the block md5 hash when @@ -1107,7 +1239,7 @@ static tng_function_status tng_md5_hash_update(tng_trajectory_t tng_data, * error has occured. */ static tng_function_status tng_header_pointers_update - (tng_trajectory_t tng_data, const char hash_mode) + (const tng_trajectory_t tng_data, const char hash_mode) { tng_gen_block_t block; FILE *temp = tng_data->input_file; @@ -1139,7 +1271,7 @@ static tng_function_status tng_header_pointers_update contents_start_pos = ftello(tng_data->output_file); fseeko(tng_data->output_file, block->block_contents_size - 5 * - sizeof(int64_t), SEEK_CUR); + sizeof(int64_t), SEEK_CUR); tng_data->input_file = temp; @@ -1194,7 +1326,8 @@ static tng_function_status tng_header_pointers_update return(TNG_SUCCESS); } -/** Update the frame set pointers in the current frame set block, already +/** + * @brief Update the frame set pointers in the current frame set block, already * written to disk. It also updates the pointers of the blocks pointing to * the current frame set block. * @param tng_data is a trajectory data container. @@ -1204,7 +1337,7 @@ static tng_function_status tng_header_pointers_update * error has occured. */ static tng_function_status tng_frame_set_pointers_update - (tng_trajectory_t tng_data, const char hash_mode) + (const tng_trajectory_t tng_data, const char hash_mode) { tng_gen_block_t block; tng_trajectory_frame_set_t frame_set; @@ -1230,8 +1363,7 @@ static tng_function_status tng_frame_set_pointers_update /* Update next frame set */ if(frame_set->next_frame_set_file_pos > 0) { - fseeko(tng_data->output_file, frame_set->next_frame_set_file_pos, - SEEK_SET); + fseeko(tng_data->output_file, frame_set->next_frame_set_file_pos, SEEK_SET); if(tng_block_header_read(tng_data, block) != TNG_SUCCESS) { @@ -1245,7 +1377,7 @@ static tng_function_status tng_frame_set_pointers_update contents_start_pos = ftello(tng_data->output_file); fseeko(tng_data->output_file, block->block_contents_size - (5 * - sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR); + sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR); if(tng_data->input_endianness_swap_func_64) { @@ -1270,7 +1402,6 @@ static tng_function_status tng_frame_set_pointers_update tng_md5_hash_update(tng_data, block, frame_set->next_frame_set_file_pos, contents_start_pos); } - fseeko(tng_data->output_file, output_file_pos, SEEK_SET); } /* Update previous frame set */ if(frame_set->prev_frame_set_file_pos > 0) @@ -1290,7 +1421,7 @@ static tng_function_status tng_frame_set_pointers_update contents_start_pos = ftello(tng_data->output_file); fseeko(tng_data->output_file, block->block_contents_size - (6 * - sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR); + sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR); if(tng_data->input_endianness_swap_func_64) { @@ -1315,15 +1446,14 @@ static tng_function_status tng_frame_set_pointers_update tng_md5_hash_update(tng_data, block, frame_set->prev_frame_set_file_pos, contents_start_pos); } - fseeko(tng_data->output_file, output_file_pos, SEEK_SET); } /* Update the frame set one medium stride step after */ if(frame_set->medium_stride_next_frame_set_file_pos > 0) { fseeko(tng_data->output_file, - frame_set->medium_stride_next_frame_set_file_pos, - SEEK_SET); + frame_set->medium_stride_next_frame_set_file_pos, + SEEK_SET); if(tng_block_header_read(tng_data, block) != TNG_SUCCESS) { @@ -1337,7 +1467,7 @@ static tng_function_status tng_frame_set_pointers_update contents_start_pos = ftello(tng_data->output_file); fseeko(tng_data->output_file, block->block_contents_size - (3 * - sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR); + sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR); if(tng_data->input_endianness_swap_func_64) { @@ -1383,7 +1513,7 @@ static tng_function_status tng_frame_set_pointers_update contents_start_pos = ftello(tng_data->output_file); fseeko(tng_data->output_file, block->block_contents_size - (4 * - sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR); + sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR); if(tng_data->input_endianness_swap_func_64) { @@ -1476,7 +1606,7 @@ static tng_function_status tng_frame_set_pointers_update contents_start_pos = ftello(tng_data->output_file); fseeko(tng_data->output_file, block->block_contents_size - (2 * - sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR); + sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR); if(tng_data->input_endianness_swap_func_64) { @@ -1514,7 +1644,7 @@ static tng_function_status tng_frame_set_pointers_update } static tng_function_status tng_reread_frame_set_at_file_pos - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t pos) { tng_gen_block_t block; @@ -1548,7 +1678,7 @@ static tng_function_status tng_reread_frame_set_at_file_pos } static tng_function_status tng_file_pos_of_subsequent_trajectory_block_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, int64_t *pos) { int64_t orig_pos, curr_frame_set_pos; @@ -1628,13 +1758,21 @@ static tng_function_status tng_file_pos_of_subsequent_trajectory_block_get return(TNG_SUCCESS); } +/** + * @brief Migrate a whole frame set from one position in the file to another. + * @param tng_data is a trajectory data container. + * @param block_start_pos is the starting position in the file of the frame set. + * @param block_len is the length of the whole frame set (including all data blocks etc). + * @param new_pos is the new position in the file of the frame set. + * @param hash_mode is an option to decide whether to generate/update the relevant md5 hashes. + */ static tng_function_status tng_frame_set_complete_migrate - (tng_trajectory_t tng_data, - int64_t block_start_pos, - int64_t block_len, - int64_t new_pos) + (const tng_trajectory_t tng_data, + const int64_t block_start_pos, + const int64_t block_len, + const int64_t new_pos, + const char hash_mode) { - int64_t i; tng_bool updated = TNG_FALSE; char *contents; @@ -1673,7 +1811,7 @@ static tng_function_status tng_frame_set_complete_migrate tng_data->current_trajectory_frame_set_output_file_pos = new_pos; - tng_frame_set_pointers_update(tng_data, TNG_USE_HASH); + tng_frame_set_pointers_update(tng_data, hash_mode); /* Update the general info block if needed */ if(block_start_pos == tng_data->first_trajectory_frame_set_output_file_pos) @@ -1688,14 +1826,11 @@ static tng_function_status tng_frame_set_complete_migrate } if(updated) { - tng_header_pointers_update(tng_data, TNG_USE_HASH); + tng_header_pointers_update(tng_data, hash_mode); } /* Fill the block with NULL to avoid confusion. */ - for(i = 0; i < block_len; i++) - { - contents[i] = '\0'; - } + memset(contents, '\0', block_len); fseeko(tng_data->output_file, block_start_pos, SEEK_SET); /* FIXME: casting block_len to size_t is dangerous */ @@ -1707,7 +1842,7 @@ static tng_function_status tng_frame_set_complete_migrate } static tng_function_status tng_length_of_current_frame_set_contents_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, int64_t *len) { int64_t orig_pos, pos, curr_frame_set_pos; @@ -1759,38 +1894,37 @@ static tng_function_status tng_length_of_current_frame_set_contents_get return(TNG_SUCCESS); } -/** Migrate blocks in the file to make room for new data in a block. This +/** + * @brief Migrate blocks in the file to make room for new data in a block. This * is required e.g. when adding data to a block or extending strings in a * block. * @param tng_data is a trajectory data container. * @param start_pos is the position from which to start moving data, usually * the byte after the end of the block to which data was added. * @param offset is the number of bytes that were inserted. + * @param hash_mode is an option to decide whether to generate/update the relevant md5 hashes. * @details Trajectory blocks (frame sets and their related blocks) are moved * to the end of the file (if needed) in order to make room for non-trajectory * data. */ static tng_function_status tng_migrate_data_in_file - (tng_trajectory_t tng_data, - int64_t start_pos, - int64_t offset) + (const tng_trajectory_t tng_data, + const int64_t start_pos, + const int64_t offset, + const char hash_mode) { int64_t traj_start_pos, empty_space, orig_file_pos, frame_set_length; tng_gen_block_t block; tng_function_status stat; - FILE *temp; if(offset <= 0) { return(TNG_SUCCESS); } - temp = tng_data->input_file; - stat = tng_file_pos_of_subsequent_trajectory_block_get(tng_data, &traj_start_pos); if(stat != TNG_SUCCESS) { - tng_data->input_file = temp; return(stat); } @@ -1815,27 +1949,24 @@ static tng_function_status tng_migrate_data_in_file fprintf(stderr, "TNG library: Cannot read block header. %s: %d\n", __FILE__, __LINE__); tng_block_destroy(&block); - tng_data->input_file = temp; return(TNG_CRITICAL); } if(stat != TNG_SUCCESS || block->id != TNG_TRAJECTORY_FRAME_SET) { - tng_data->input_file = temp; tng_block_destroy(&block); return(TNG_FAILURE); } stat = tng_length_of_current_frame_set_contents_get(tng_data, &frame_set_length); if(stat != TNG_SUCCESS) { - tng_data->input_file = temp; tng_block_destroy(&block); return(stat); } stat = tng_frame_set_complete_migrate(tng_data, traj_start_pos, - frame_set_length, tng_data->input_file_len); + frame_set_length, tng_data->input_file_len, + hash_mode); if(stat != TNG_SUCCESS) { - tng_data->input_file = temp; tng_block_destroy(&block); return(stat); } @@ -1850,7 +1981,7 @@ static tng_function_status tng_migrate_data_in_file static tng_function_status tng_block_header_len_calculate (const tng_trajectory_t tng_data, - tng_gen_block_t block, + const tng_gen_block_t block, int64_t *len) { int name_len; @@ -1870,7 +2001,7 @@ static tng_function_status tng_block_header_len_calculate block->name[0] = 0; } - name_len = tng_min_i((int)strlen(block->name) + 1, TNG_MAX_STR_LEN); + name_len = tng_min_size(strlen(block->name) + 1, TNG_MAX_STR_LEN); /* Calculate the size of the header to write */ *len = sizeof(block->header_contents_size) + @@ -1883,7 +2014,8 @@ static tng_function_status tng_block_header_len_calculate return (TNG_SUCCESS); } -/** Write the header of a data block, regardless of its type +/** + * @brief Write the header of a data block, regardless of its type * @param tng_data is a trajectory data container. * @param block is a general block container. * @param hash_mode is an option to decide whether to use the md5 hash or not. @@ -1892,12 +2024,9 @@ static tng_function_status tng_block_header_len_calculate * error has occured. */ static tng_function_status tng_block_header_write - (tng_trajectory_t tng_data, - tng_gen_block_t block, - const char hash_mode) + (const tng_trajectory_t tng_data, + const tng_gen_block_t block) { - int name_len, offset = 0; - TNG_ASSERT(block != 0, "TNG library: Trying to write uninitialized block (NULL pointer)."); if(tng_output_file_init(tng_data) != TNG_SUCCESS) @@ -1915,106 +2044,57 @@ static tng_function_status tng_block_header_write return(TNG_CRITICAL); } - if(hash_mode == TNG_USE_HASH) - { - tng_block_md5_hash_generate(block); - } - - if(block->header_contents) - { - free(block->header_contents); - } - - block->header_contents = malloc(block->header_contents_size); - if(!block->header_contents) + if(tng_file_output_numerical(tng_data, &block->header_contents_size, + sizeof(block->header_contents_size), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - block->header_contents_size, __FILE__, __LINE__); return(TNG_CRITICAL); } - name_len = tng_min_i((int)strlen(block->name) + 1, TNG_MAX_STR_LEN); - - /* First copy all data into the header_contents block and finally write - * the whole block at once. */ - memcpy(block->header_contents, &block->header_contents_size, - sizeof(block->header_contents_size)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &block->block_contents_size, + sizeof(block->block_contents_size), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(block->header_contents_size); - memcpy(block->header_contents+offset, &block->block_contents_size, - sizeof(block->block_contents_size)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &block->id, + sizeof(block->id), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(block->block_contents_size); - memcpy(block->header_contents+offset, &block->id, sizeof(block->id)); - if(tng_data->output_endianness_swap_func_64) + if(fwrite(block->md5_hash, TNG_MD5_HASH_LEN, 1, tng_data->output_file) != 1) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + fprintf(stderr, "TNG library: Could not write header data. %s: %d\n", __FILE__, __LINE__); + return(TNG_CRITICAL); } - offset += sizeof(block->id); - - memcpy(block->header_contents+offset, block->md5_hash, TNG_MD5_HASH_LEN); - offset += TNG_MD5_HASH_LEN; - - strncpy(block->header_contents+offset, block->name, name_len); - offset += name_len; - memcpy(block->header_contents+offset, &block->block_version, - sizeof(block->block_version)); - if(tng_data->output_endianness_swap_func_64) + if(tng_fwritestr(tng_data, block->name, TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - if(fwrite(block->header_contents, block->header_contents_size, - 1, tng_data->output_file) != 1) + if(tng_file_output_numerical(tng_data, &block->block_version, + sizeof(block->block_version), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Could not write all header data. %s: %d\n", __FILE__, __LINE__); return(TNG_CRITICAL); } + return(TNG_SUCCESS); } static tng_function_status tng_general_info_block_len_calculate - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, int64_t *len) { - int first_program_name_len, first_user_name_len; - int first_computer_name_len, first_pgp_signature_len; - int last_program_name_len, last_user_name_len; - int last_computer_name_len, last_pgp_signature_len; - int forcefield_name_len; + size_t first_program_name_len, first_user_name_len; + size_t first_computer_name_len, first_pgp_signature_len; + size_t last_program_name_len, last_user_name_len; + size_t last_computer_name_len, last_pgp_signature_len; + size_t forcefield_name_len; /* If the strings are unallocated allocate memory for just string * termination */ @@ -2118,23 +2198,23 @@ static tng_function_status tng_general_info_block_len_calculate tng_data->forcefield_name[0] = 0; } - first_program_name_len = tng_min_i((int)strlen(tng_data->first_program_name) + 1, + first_program_name_len = tng_min_size(strlen(tng_data->first_program_name) + 1, TNG_MAX_STR_LEN); - last_program_name_len = tng_min_i((int)strlen(tng_data->last_program_name) + 1, + last_program_name_len = tng_min_size(strlen(tng_data->last_program_name) + 1, TNG_MAX_STR_LEN); - first_user_name_len = tng_min_i((int)strlen(tng_data->first_user_name) + 1, + first_user_name_len = tng_min_size(strlen(tng_data->first_user_name) + 1, TNG_MAX_STR_LEN); - last_user_name_len = tng_min_i((int)strlen(tng_data->last_user_name) + 1, + last_user_name_len = tng_min_size(strlen(tng_data->last_user_name) + 1, TNG_MAX_STR_LEN); - first_computer_name_len = tng_min_i((int)strlen(tng_data->first_computer_name) + 1, + first_computer_name_len = tng_min_size(strlen(tng_data->first_computer_name) + 1, TNG_MAX_STR_LEN); - last_computer_name_len = tng_min_i((int)strlen(tng_data->last_computer_name) + 1, + last_computer_name_len = tng_min_size(strlen(tng_data->last_computer_name) + 1, TNG_MAX_STR_LEN); - first_pgp_signature_len = tng_min_i((int)strlen(tng_data->first_pgp_signature) + 1, + first_pgp_signature_len = tng_min_size(strlen(tng_data->first_pgp_signature) + 1, TNG_MAX_STR_LEN); - last_pgp_signature_len = tng_min_i((int)strlen(tng_data->last_pgp_signature) + 1, + last_pgp_signature_len = tng_min_size(strlen(tng_data->last_pgp_signature) + 1, TNG_MAX_STR_LEN); - forcefield_name_len = tng_min_i((int)strlen(tng_data->forcefield_name) + 1, + forcefield_name_len = tng_min_size(strlen(tng_data->forcefield_name) + 1, TNG_MAX_STR_LEN); *len = sizeof(tng_data->time) + @@ -2158,8 +2238,9 @@ static tng_function_status tng_general_info_block_len_calculate return(TNG_SUCCESS); } -/** Read a general info block. This is the first block of a TNG file. - * Populate the fields in tng_data. +/** + * @brief Read a general info block. This is the first block of a TNG file. + * Populate the fields in tng_data. * @param tng_data is a trajectory data container. * @param block is a general block container. * @param hash_mode is an option to decide whether to use the md5 hash or not. @@ -2169,13 +2250,13 @@ static tng_function_status tng_general_info_block_len_calculate * error has occured. */ static tng_function_status tng_general_info_block_read - (tng_trajectory_t tng_data, tng_gen_block_t block, + (const tng_trajectory_t tng_data, + const tng_gen_block_t block, const char hash_mode) { - int len, offset = 0; - tng_bool same_hash; - - void *temp; + int64_t start_pos; + char hash[TNG_MD5_HASH_LEN]; + md5_state_t md5_state; TNG_ASSERT(block != 0, "TNG library: Trying to read data to an uninitialized block (NULL pointer)"); @@ -2184,315 +2265,156 @@ static tng_function_status tng_general_info_block_read return(TNG_CRITICAL); } - temp = realloc(block->block_contents, block->block_contents_size); - if(!temp) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - block->block_contents_size, __FILE__, __LINE__); - free(block->block_contents); - block->block_contents = 0; - return(TNG_CRITICAL); - } - block->block_contents = temp; + start_pos = ftello(tng_data->input_file); - /* 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) + if(hash_mode == TNG_USE_HASH) { - fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, __LINE__); - return(TNG_CRITICAL); + md5_init(&md5_state); } - /* FIXME: Does not check if the size of the contents matches the expected - * size or if the contents can be read. */ + tng_freadstr(tng_data, &tng_data->first_program_name, hash_mode, &md5_state, __LINE__); - if(hash_mode == TNG_USE_HASH) - { - tng_md5_hash_match_verify(block, &same_hash); - if(same_hash != TNG_TRUE) - { - fprintf(stderr, "TNG library: General info block contents corrupt. Hashes do not match. " - "%s: %d\n", - __FILE__, __LINE__); - /* return(TNG_FAILURE); */ - } - } + tng_freadstr(tng_data, &tng_data->last_program_name, hash_mode, &md5_state, __LINE__); - len = tng_min_i((int)strlen(block->block_contents) + 1, TNG_MAX_STR_LEN); - temp = realloc(tng_data->first_program_name, len); - if(!temp) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len, - __FILE__, __LINE__); - free(tng_data->first_program_name); - tng_data->first_program_name = 0; - return(TNG_CRITICAL); - } - tng_data->first_program_name = temp; - strncpy(tng_data->first_program_name, block->block_contents, len); - offset += len; + tng_freadstr(tng_data, &tng_data->first_user_name, hash_mode, &md5_state, __LINE__); - len = tng_min_i((int)strlen(block->block_contents + offset) + 1, TNG_MAX_STR_LEN); - temp = realloc(tng_data->last_program_name, len); - if(!temp) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len, - __FILE__, __LINE__); - free(tng_data->last_program_name); - tng_data->last_program_name = 0; - return(TNG_CRITICAL); - } - tng_data->last_program_name = temp; - strncpy(tng_data->last_program_name, block->block_contents + offset, len); - offset += len; + tng_freadstr(tng_data, &tng_data->last_user_name, hash_mode, &md5_state, __LINE__); - len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN); - temp = realloc(tng_data->first_user_name, len); - if(!temp) + tng_freadstr(tng_data, &tng_data->first_computer_name, hash_mode, &md5_state, __LINE__); + + tng_freadstr(tng_data, &tng_data->last_computer_name, hash_mode, &md5_state, __LINE__); + + tng_freadstr(tng_data, &tng_data->first_pgp_signature, hash_mode, &md5_state, __LINE__); + + tng_freadstr(tng_data, &tng_data->last_pgp_signature, hash_mode, &md5_state, __LINE__); + + tng_freadstr(tng_data, &tng_data->forcefield_name, hash_mode, &md5_state, __LINE__); + + if(tng_file_input_numerical(tng_data, &tng_data->time, sizeof(tng_data->time), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len, - __FILE__, __LINE__); - free(tng_data->first_user_name); - tng_data->first_user_name = 0; return(TNG_CRITICAL); } - tng_data->first_user_name = temp; - strncpy(tng_data->first_user_name, block->block_contents+offset, len); - offset += len; - len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN); - temp = realloc(tng_data->last_user_name, len); - if(!temp) + + if(tng_file_input_numerical(tng_data, &tng_data->var_num_atoms_flag, + sizeof(tng_data->var_num_atoms_flag), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len, - __FILE__, __LINE__); - free(tng_data->last_user_name); - tng_data->last_user_name = 0; return(TNG_CRITICAL); } - tng_data->last_user_name = temp; - strncpy(tng_data->last_user_name, block->block_contents+offset, len); - offset += len; - len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN); - temp = realloc(tng_data->first_computer_name, len); - if(!temp) + if(tng_file_input_numerical(tng_data, &tng_data->frame_set_n_frames, + sizeof(tng_data->frame_set_n_frames), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len, - __FILE__, __LINE__); - free(tng_data->first_computer_name); - tng_data->first_computer_name = 0; return(TNG_CRITICAL); } - tng_data->first_computer_name = temp; - strncpy(tng_data->first_computer_name, block->block_contents+offset, len); - offset += len; - len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN); - temp = realloc(tng_data->last_computer_name, len); - if(!temp) + if(tng_file_input_numerical(tng_data, + &tng_data->first_trajectory_frame_set_input_file_pos, + sizeof(tng_data->first_trajectory_frame_set_input_file_pos), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len, - __FILE__, __LINE__); - free(tng_data->last_computer_name); - tng_data->last_computer_name = 0; return(TNG_CRITICAL); } - tng_data->last_computer_name = temp; - strncpy(tng_data->last_computer_name, block->block_contents+offset, len); - offset += len; - len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN); - temp = realloc(tng_data->first_pgp_signature, len); - if(!temp) + tng_data->current_trajectory_frame_set.next_frame_set_file_pos = + tng_data->first_trajectory_frame_set_input_file_pos; + + if(tng_file_input_numerical(tng_data, + &tng_data->last_trajectory_frame_set_input_file_pos, + sizeof(tng_data->last_trajectory_frame_set_input_file_pos), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len, - __FILE__, __LINE__); - free(tng_data->first_pgp_signature); - tng_data->first_pgp_signature = 0; return(TNG_CRITICAL); } - tng_data->first_pgp_signature = temp; - strncpy(tng_data->first_pgp_signature, block->block_contents+offset, len); - offset += len; - len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN); - temp = realloc(tng_data->last_pgp_signature, len); - if(!temp) + if(tng_file_input_numerical(tng_data, + &tng_data->medium_stride_length, + sizeof(tng_data->medium_stride_length), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len, - __FILE__, __LINE__); - free(tng_data->last_pgp_signature); - tng_data->last_pgp_signature = 0; return(TNG_CRITICAL); } - tng_data->last_pgp_signature = temp; - strncpy(tng_data->last_pgp_signature, block->block_contents+offset, len); - offset += len; - len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN); - temp = realloc(tng_data->forcefield_name, len); - if(!temp) + if(tng_file_input_numerical(tng_data, + &tng_data->long_stride_length, + sizeof(tng_data->long_stride_length), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len, - __FILE__, __LINE__); - free(tng_data->forcefield_name); - tng_data->forcefield_name = 0; return(TNG_CRITICAL); } - tng_data->forcefield_name = temp; - strncpy(tng_data->forcefield_name, block->block_contents+offset, len); - offset += len; - memcpy(&tng_data->time, block->block_contents+offset, - sizeof(tng_data->time)); - if(tng_data->input_endianness_swap_func_64) + if(block->block_version >= 3) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &tng_data->time) - != TNG_SUCCESS) + if(tng_file_input_numerical(tng_data, + &tng_data->distance_unit_exponential, + sizeof(tng_data->distance_unit_exponential), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); + return(TNG_CRITICAL); } } - offset += sizeof(tng_data->time); - - memcpy(&tng_data->var_num_atoms_flag, block->block_contents+offset, - sizeof(tng_data->var_num_atoms_flag)); - offset += sizeof(tng_data->var_num_atoms_flag); - memcpy(&tng_data->frame_set_n_frames, block->block_contents+offset, - sizeof(tng_data->frame_set_n_frames)); - if(tng_data->input_endianness_swap_func_64) + if(hash_mode == TNG_USE_HASH) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &tng_data->frame_set_n_frames) - != TNG_SUCCESS) + /* If there is data left in the block that the current version of the library + * cannot interpret still read that to generate the MD5 hash. */ + tng_md5_remaining_append(tng_data, block, start_pos, &md5_state); + + md5_finish(&md5_state, (md5_byte_t *)hash); + if(strncmp(block->md5_hash, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", TNG_MD5_HASH_LEN) != 0) { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); + if(strncmp(block->md5_hash, hash, TNG_MD5_HASH_LEN) != 0) + { + fprintf(stderr, "TNG library: General info block contents corrupt. Hashes do not match. " + "%s: %d\n", __FILE__, __LINE__); + } } } - offset += sizeof(tng_data->frame_set_n_frames); - - memcpy(&tng_data->first_trajectory_frame_set_input_file_pos, - block->block_contents+offset, - sizeof(tng_data->first_trajectory_frame_set_input_file_pos)); - if(tng_data->input_endianness_swap_func_64) + else { - if(tng_data->input_endianness_swap_func_64(tng_data, - &tng_data->first_trajectory_frame_set_input_file_pos) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + /* Seek to the end of the block */ + fseeko(tng_data->input_file, start_pos + block->block_contents_size, SEEK_SET); } - offset += sizeof(tng_data->first_trajectory_frame_set_input_file_pos); - tng_data->current_trajectory_frame_set.next_frame_set_file_pos = - tng_data->first_trajectory_frame_set_input_file_pos; + return(TNG_SUCCESS); +} +/** + * @brief Write a general info block. This is the first block of a TNG file. + * @param tng_data is a trajectory data container. + * @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 will be generated and written. + * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major + * error has occured. + */ +static tng_function_status tng_general_info_block_write + (const tng_trajectory_t tng_data, + const char hash_mode) +{ + int64_t header_file_pos, curr_file_pos; + size_t name_len; + tng_gen_block_t block; + md5_state_t md5_state; - memcpy(&tng_data->last_trajectory_frame_set_input_file_pos, - block->block_contents+offset, - sizeof(tng_data->last_trajectory_frame_set_input_file_pos)); - if(tng_data->input_endianness_swap_func_64) + if(tng_output_file_init(tng_data) != TNG_SUCCESS) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &tng_data->last_trajectory_frame_set_input_file_pos) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(tng_data->last_trajectory_frame_set_input_file_pos); - memcpy(&tng_data->medium_stride_length, block->block_contents+offset, - sizeof(tng_data->medium_stride_length)); - if(tng_data->input_endianness_swap_func_64) - { - if(tng_data->input_endianness_swap_func_64(tng_data, - &tng_data->medium_stride_length) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - offset += sizeof(tng_data->medium_stride_length); - - memcpy(&tng_data->long_stride_length, block->block_contents+offset, - sizeof(tng_data->long_stride_length)); - if(tng_data->input_endianness_swap_func_64) - { - if(tng_data->input_endianness_swap_func_64(tng_data, - &tng_data->long_stride_length) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - offset += sizeof(tng_data->long_stride_length); - - if(block->block_version >= 3) - { - memcpy(&tng_data->distance_unit_exponential, block->block_contents+offset, - sizeof(tng_data->distance_unit_exponential)); - if(tng_data->input_endianness_swap_func_64) - { - if(tng_data->input_endianness_swap_func_64(tng_data, - &tng_data->distance_unit_exponential) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - } - - return(TNG_SUCCESS); -} - -/** Write a general info block. This is the first block of a TNG file. - * @param tng_data is a trajectory data container. - * @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 will be generated and written. - * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major - * error has occured. - */ -static tng_function_status tng_general_info_block_write - (tng_trajectory_t tng_data, - const char hash_mode) -{ - int first_program_name_len, first_user_name_len; - int first_computer_name_len, first_pgp_signature_len; - int last_program_name_len, last_user_name_len; - int last_computer_name_len, last_pgp_signature_len; - int forcefield_name_len, name_len; - int offset = 0; - tng_gen_block_t block; - - if(tng_output_file_init(tng_data) != TNG_SUCCESS) - { - return(TNG_CRITICAL); - } - - fseeko(tng_data->output_file, 0, SEEK_SET); + fseeko(tng_data->output_file, 0, SEEK_SET); tng_block_init(&block); - name_len = (int)strlen("GENERAL INFO"); + name_len = strlen("GENERAL INFO"); block->name = malloc(name_len + 1); if(!block->name) { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", - name_len+1, __FILE__, __LINE__); + fprintf(stderr, "TNG library: Cannot allocate memory (%u bytes). %s: %d\n", + (unsigned int)(name_len+1), __FILE__, __LINE__); tng_block_destroy(&block); return(TNG_CRITICAL); } @@ -2509,486 +2431,350 @@ static tng_function_status tng_general_info_block_write return(TNG_CRITICAL); } - first_program_name_len = tng_min_i((int)strlen(tng_data->first_program_name) + 1, - TNG_MAX_STR_LEN); - last_program_name_len = tng_min_i((int)strlen(tng_data->last_program_name) + 1, - TNG_MAX_STR_LEN); - first_user_name_len = tng_min_i((int)strlen(tng_data->first_user_name) + 1, - TNG_MAX_STR_LEN); - last_user_name_len = tng_min_i((int)strlen(tng_data->last_user_name) + 1, - TNG_MAX_STR_LEN); - first_computer_name_len = tng_min_i((int)strlen(tng_data->first_computer_name) + 1, - TNG_MAX_STR_LEN); - last_computer_name_len = tng_min_i((int)strlen(tng_data->last_computer_name) + 1, - TNG_MAX_STR_LEN); - first_pgp_signature_len = tng_min_i((int)strlen(tng_data->first_pgp_signature) + 1, - TNG_MAX_STR_LEN); - last_pgp_signature_len = tng_min_i((int)strlen(tng_data->last_pgp_signature) + 1, - TNG_MAX_STR_LEN); - forcefield_name_len = tng_min_i((int)strlen(tng_data->forcefield_name) + 1, - TNG_MAX_STR_LEN); + header_file_pos = 0; - if(block->block_contents) - { - free(block->block_contents); - } - block->block_contents = malloc(block->block_contents_size); - if(!block->block_contents) + if(tng_block_header_write(tng_data, block) != TNG_SUCCESS) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - block->block_contents_size, __FILE__, __LINE__); + fprintf(stderr, "TNG library: Cannot write header of file %s. %s: %d\n", + tng_data->output_file_path, __FILE__, __LINE__); tng_block_destroy(&block); return(TNG_CRITICAL); } - strncpy(block->block_contents, tng_data->first_program_name, first_program_name_len); - offset += first_program_name_len; + if(hash_mode == TNG_USE_HASH) + { + md5_init(&md5_state); + } - strncpy(block->block_contents+offset, tng_data->last_program_name, last_program_name_len); - offset += last_program_name_len; + if(tng_fwritestr(tng_data, tng_data->first_program_name, + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } - strncpy(block->block_contents+offset, tng_data->first_user_name, first_user_name_len); - offset += first_user_name_len; + if(tng_fwritestr(tng_data, tng_data->last_program_name, + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } - strncpy(block->block_contents+offset, tng_data->last_user_name, last_user_name_len); - offset += last_user_name_len; + if(tng_fwritestr(tng_data, tng_data->first_user_name, + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } - strncpy(block->block_contents+offset, tng_data->first_computer_name, - first_computer_name_len); - offset += first_computer_name_len; + if(tng_fwritestr(tng_data, tng_data->last_user_name, + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } - strncpy(block->block_contents+offset, tng_data->last_computer_name, - last_computer_name_len); - offset += last_computer_name_len; + if(tng_fwritestr(tng_data, tng_data->first_computer_name, + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } - strncpy(block->block_contents+offset, tng_data->first_pgp_signature, - first_pgp_signature_len); - offset += first_pgp_signature_len; + if(tng_fwritestr(tng_data, tng_data->last_computer_name, + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } - strncpy(block->block_contents+offset, tng_data->last_pgp_signature, - last_pgp_signature_len); - offset += last_pgp_signature_len; + if(tng_fwritestr(tng_data, tng_data->first_pgp_signature, + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } - strncpy(block->block_contents+offset, tng_data->forcefield_name, - forcefield_name_len); - offset += forcefield_name_len; + if(tng_fwritestr(tng_data, tng_data->last_pgp_signature, + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } - memcpy(block->block_contents+offset, &tng_data->time, - sizeof(tng_data->time)); - if(tng_data->output_endianness_swap_func_64) + if(tng_fwritestr(tng_data, tng_data->forcefield_name, + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(tng_data->time); - memcpy(block->block_contents+offset, &tng_data->var_num_atoms_flag, - sizeof(tng_data->var_num_atoms_flag)); - offset += sizeof(tng_data->var_num_atoms_flag); - memcpy(block->block_contents+offset, &tng_data->frame_set_n_frames, - sizeof(tng_data->frame_set_n_frames)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &tng_data->time, sizeof(tng_data->time), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(tng_data->frame_set_n_frames); - memcpy(block->block_contents+offset, - &tng_data->first_trajectory_frame_set_output_file_pos, - sizeof(tng_data->first_trajectory_frame_set_output_file_pos)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &tng_data->var_num_atoms_flag, + sizeof(tng_data->var_num_atoms_flag), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(tng_data->first_trajectory_frame_set_output_file_pos); - memcpy(block->block_contents+offset, - &tng_data->last_trajectory_frame_set_output_file_pos, - sizeof(tng_data->last_trajectory_frame_set_output_file_pos)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &tng_data->frame_set_n_frames, + sizeof(tng_data->frame_set_n_frames), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(tng_data->last_trajectory_frame_set_output_file_pos); - memcpy(block->block_contents+offset, &tng_data->medium_stride_length, - sizeof(tng_data->medium_stride_length)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &tng_data->first_trajectory_frame_set_output_file_pos, + sizeof(tng_data->first_trajectory_frame_set_output_file_pos), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(tng_data->medium_stride_length); - memcpy(block->block_contents+offset, &tng_data->long_stride_length, - sizeof(tng_data->long_stride_length)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &tng_data->last_trajectory_frame_set_output_file_pos, + sizeof(tng_data->last_trajectory_frame_set_output_file_pos), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(tng_data->long_stride_length); - memcpy(block->block_contents+offset, &tng_data->distance_unit_exponential, - sizeof(tng_data->distance_unit_exponential)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &tng_data->medium_stride_length, + sizeof(tng_data->medium_stride_length), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - if(tng_block_header_write(tng_data, block, hash_mode) != TNG_SUCCESS) + if(tng_file_output_numerical(tng_data, &tng_data->long_stride_length, + sizeof(tng_data->long_stride_length), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot write header of file %s. %s: %d\n", - tng_data->output_file_path, __FILE__, __LINE__); - tng_block_destroy(&block); return(TNG_CRITICAL); } - if(fwrite(block->block_contents, block->block_contents_size, 1, - tng_data->output_file) != 1) + if(tng_file_output_numerical(tng_data, &tng_data->distance_unit_exponential, + sizeof(tng_data->distance_unit_exponential), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Could not write all block data. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); return(TNG_CRITICAL); } + if(hash_mode == TNG_USE_HASH) + { + md5_finish(&md5_state, (md5_byte_t *)block->md5_hash); + curr_file_pos = ftello(tng_data->output_file); + fseeko(tng_data->output_file, header_file_pos + + 3 * sizeof(int64_t), SEEK_SET); + if(fwrite(block->md5_hash, TNG_MD5_HASH_LEN, 1, tng_data->output_file) != 1) + { + fprintf(stderr, "TNG library: Could not write MD5 hash. %s: %d\n", __FILE__, + __LINE__); + return(TNG_CRITICAL); + } + fseeko(tng_data->output_file, curr_file_pos, SEEK_SET); + } tng_block_destroy(&block); return(TNG_SUCCESS); } -/** Read the chain data of a molecules block. +/** + * @brief Read the chain data of a molecules block. * @param tng_data is a trajectory data container. - * @param block is a general block container. * @param chain is the chain data container. - * @param offset is the offset of the block input and is updated when reading. + * @param hash_mode is an option to decide whether to generate/update the relevant md5 hashes. + * @param md5_state is a pointer to the current md5 storage, which will be updated appropriately + * if hash_mode == TNG_USE_HASH. * @return TNG_SUCCESS(0) is successful. */ -static tng_function_status tng_chain_data_read(tng_trajectory_t tng_data, - tng_gen_block_t block, - tng_chain_t chain, - int *offset) +static tng_function_status tng_chain_data_read(const tng_trajectory_t tng_data, + const tng_chain_t chain, + const char hash_mode, + md5_state_t *md5_state) { - int len; - - TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer."); - - memcpy(&chain->id, block->block_contents+*offset, - sizeof(chain->id)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &chain->id, + sizeof(chain->id), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &chain->id) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - *offset += sizeof(chain->id); - len = tng_min_i((int)strlen(block->block_contents+*offset) + 1, - TNG_MAX_STR_LEN); - chain->name = malloc(len); - strncpy(chain->name, - block->block_contents+*offset, len); - *offset += len; + tng_freadstr(tng_data, &chain->name, hash_mode, md5_state, __LINE__); - memcpy(&chain->n_residues, block->block_contents+*offset, - sizeof(chain->n_residues)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &chain->n_residues, + sizeof(chain->n_residues), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &chain->n_residues) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - *offset += sizeof(chain->n_residues); return(TNG_SUCCESS); } -/** Write the chain data of a molecules block. +/** + * @brief Write the chain data of a molecules block. * @param tng_data is a trajectory data container. - * @param block is a general block container. * @param chain is the chain data container. - * @param offset is the offset of the block output and is updated when writing. + * @param hash_mode is an option to decide whether to generate/update the relevant md5 hashes. + * @param md5_state is a pointer to the current md5 storage, which will be updated appropriately + * if hash_mode == TNG_USE_HASH. * @return TNG_SUCCESS(0) is successful. */ -static tng_function_status tng_chain_data_write(tng_trajectory_t tng_data, - tng_gen_block_t block, - tng_chain_t chain, - int *offset) +static tng_function_status tng_chain_data_write(const tng_trajectory_t tng_data, + const tng_chain_t chain, + const char hash_mode, + md5_state_t *md5_state) { - int len; - - TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer."); - - memcpy(block->block_contents+*offset, &chain->id, sizeof(chain->id)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &chain->id, + sizeof(chain->id), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+*offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - *offset += sizeof(chain->id); - len = tng_min_i((int)strlen(chain->name) + 1, TNG_MAX_STR_LEN); - strncpy(block->block_contents + *offset, chain->name, len); - *offset += len; + if(tng_fwritestr(tng_data, chain->name, hash_mode, + md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } - memcpy(block->block_contents+*offset, &chain->n_residues, - sizeof(chain->n_residues)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &chain->n_residues, + sizeof(chain->n_residues), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+*offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - *offset += sizeof(chain->n_residues); return(TNG_SUCCESS); } -/** Read the residue data of a molecules block. +/** + * @brief Read the residue data of a molecules block. * @param tng_data is a trajectory data container. - * @param block is a general block container. * @param residue is the residue data container. - * @param offset is the offset of the block input and is updated when reading. + * @param hash_mode is an option to decide whether to generate/update the relevant md5 hashes. + * @param md5_state is a pointer to the current md5 storage, which will be updated appropriately + * if hash_mode == TNG_USE_HASH. * @return TNG_SUCCESS(0) is successful. */ -static tng_function_status tng_residue_data_read(tng_trajectory_t tng_data, - tng_gen_block_t block, - tng_residue_t residue, - int *offset) +static tng_function_status tng_residue_data_read(const tng_trajectory_t tng_data, + const tng_residue_t residue, + const char hash_mode, + md5_state_t *md5_state) { - int len; - - TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer."); - - memcpy(&residue->id, block->block_contents+*offset, - sizeof(residue->id)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &residue->id, + sizeof(residue->id), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &residue->id) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - *offset += sizeof(residue->id); - len = tng_min_i((int)strlen(block->block_contents+*offset) + 1, - TNG_MAX_STR_LEN); - residue->name = malloc(len); - strncpy(residue->name, - block->block_contents+*offset, len); - *offset += len; + tng_freadstr(tng_data, &residue->name, hash_mode, md5_state, __LINE__); - memcpy(&residue->n_atoms, block->block_contents+*offset, - sizeof(residue->n_atoms)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &residue->n_atoms, + sizeof(residue->n_atoms), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &residue->n_atoms) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - *offset += sizeof(residue->n_atoms); return(TNG_SUCCESS); } -/** Write the residue data of a molecules block. +/** + * @brief Write the residue data of a molecules block. * @param tng_data is a trajectory data container. - * @param block is a general block container. * @param residue is the residue data container. - * @param offset is the offset of the block output and is updated when writing. + * @param hash_mode is an option to decide whether to generate/update the relevant md5 hashes. + * @param md5_state is a pointer to the current md5 storage, which will be updated appropriately + * if hash_mode == TNG_USE_HASH. * @return TNG_SUCCESS(0) is successful. */ -static tng_function_status tng_residue_data_write(tng_trajectory_t tng_data, - tng_gen_block_t block, - tng_residue_t residue, - int *offset) +static tng_function_status tng_residue_data_write(const tng_trajectory_t tng_data, + const tng_residue_t residue, + const char hash_mode, + md5_state_t *md5_state) { - int len; - - TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer."); - - memcpy(block->block_contents+*offset, &residue->id, sizeof(residue->id)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &residue->id, + sizeof(residue->id), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+*offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - *offset += sizeof(residue->id); - len = tng_min_i((int)strlen(residue->name) + 1, TNG_MAX_STR_LEN); - strncpy(block->block_contents + *offset, residue->name, len); - *offset += len; + if(tng_fwritestr(tng_data, residue->name, hash_mode, + md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } - memcpy(block->block_contents+*offset, &residue->n_atoms, - sizeof(residue->n_atoms)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &residue->n_atoms, + sizeof(residue->n_atoms), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+*offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - *offset += sizeof(residue->n_atoms); return(TNG_SUCCESS); } -/** Read the atom data of a molecules block. +/** + * @brief Read the atom data of a molecules block. * @param tng_data is a trajectory data container. - * @param block is a general block container. * @param atom is the atom data container. - * @param offset is the offset of the block input and is updated when reading. + * @param hash_mode is an option to decide whether to generate/update the relevant md5 hashes. + * @param md5_state is a pointer to the current md5 storage, which will be updated appropriately + * if hash_mode == TNG_USE_HASH. * @return TNG_SUCCESS(0) is successful. */ -static tng_function_status tng_atom_data_read(tng_trajectory_t tng_data, - tng_gen_block_t block, - tng_atom_t atom, - int *offset) +static tng_function_status tng_atom_data_read(const tng_trajectory_t tng_data, + const tng_atom_t atom, + const char hash_mode, + md5_state_t *md5_state) { - int len; - - TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer."); - - memcpy(&atom->id, block->block_contents+*offset, - sizeof(atom->id)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &atom->id, + sizeof(atom->id), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &atom->id) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - *offset += sizeof(atom->id); - len = tng_min_i((int)strlen(block->block_contents+*offset) + 1, - TNG_MAX_STR_LEN); - atom->name = malloc(len); - strncpy(atom->name, - block->block_contents+*offset, len); - *offset += len; + tng_freadstr(tng_data, &atom->name, hash_mode, md5_state, __LINE__); - len = tng_min_i((int)strlen(block->block_contents+*offset) + 1, - TNG_MAX_STR_LEN); - atom->atom_type = malloc(len); - strncpy(atom->atom_type, - block->block_contents+*offset, len); - *offset += len; + tng_freadstr(tng_data, &atom->atom_type, hash_mode, md5_state, __LINE__); return(TNG_SUCCESS); } -/** Write the atom data of a molecules block. +/** + * @brief Write the atom data of a molecules block. * @param tng_data is a trajectory data container. - * @param block is a general block container. * @param atom is the atom data container. - * @param offset is the offset of the block output and is updated when writing. + * @param hash_mode is an option to decide whether to generate/update the relevant md5 hashes. + * @param md5_state is a pointer to the current md5 storage, which will be updated appropriately + * if hash_mode == TNG_USE_HASH. * @return TNG_SUCCESS(0) is successful. */ -static tng_function_status tng_atom_data_write(tng_trajectory_t tng_data, - tng_gen_block_t block, - tng_atom_t atom, - int *offset) +static tng_function_status tng_atom_data_write(const tng_trajectory_t tng_data, + const tng_atom_t atom, + const char hash_mode, + md5_state_t *md5_state) { - int len; - - TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer."); - - memcpy(block->block_contents+*offset, &atom->id, - sizeof(atom->id)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &atom->id, + sizeof(atom->id), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+*offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - *offset += sizeof(atom->id); - len = tng_min_i((int)strlen(atom->name) + 1, TNG_MAX_STR_LEN); - strncpy(block->block_contents + *offset, atom->name, len); - *offset += len; + if(tng_fwritestr(tng_data, atom->name, hash_mode, + md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } - len = tng_min_i((int)strlen(atom->atom_type) + 1, TNG_MAX_STR_LEN); - strncpy(block->block_contents + *offset, atom->atom_type, len); - *offset += len; + if(tng_fwritestr(tng_data, atom->atom_type, hash_mode, + md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } return(TNG_SUCCESS); } @@ -3020,7 +2806,7 @@ static tng_function_status tng_molecules_block_len_calculate } molecule->name[0] = 0; } - *len += tng_min_i((int)strlen(molecule->name) + 1, TNG_MAX_STR_LEN); + *len += tng_min_size(strlen(molecule->name) + 1, TNG_MAX_STR_LEN); chain = molecule->chains; for(j = 0; j < molecule->n_chains; j++) @@ -3038,7 +2824,7 @@ static tng_function_status tng_molecules_block_len_calculate } chain->name[0] = 0; } - *len += tng_min_i((int)strlen(chain->name) + 1, TNG_MAX_STR_LEN); + *len += tng_min_size(strlen(chain->name) + 1, TNG_MAX_STR_LEN); *len += sizeof(chain->n_residues); @@ -3061,7 +2847,7 @@ static tng_function_status tng_molecules_block_len_calculate } residue->name[0] = 0; } - *len += tng_min_i((int)strlen(residue->name) + 1, TNG_MAX_STR_LEN); + *len += tng_min_size(strlen(residue->name) + 1, TNG_MAX_STR_LEN); *len += sizeof(residue->n_atoms); @@ -3083,7 +2869,7 @@ static tng_function_status tng_molecules_block_len_calculate } atom->name[0] = 0; } - *len += tng_min_i((int)strlen(atom->name) + 1, TNG_MAX_STR_LEN); + *len += tng_min_size(strlen(atom->name) + 1, TNG_MAX_STR_LEN); if(!atom->atom_type) { @@ -3096,7 +2882,7 @@ static tng_function_status tng_molecules_block_len_calculate } atom->atom_type[0] = 0; } - *len += tng_min_i((int)strlen(atom->atom_type) + 1, TNG_MAX_STR_LEN); + *len += tng_min_size(strlen(atom->atom_type) + 1, TNG_MAX_STR_LEN); atom++; } @@ -3123,7 +2909,8 @@ static tng_function_status tng_molecules_block_len_calculate return(TNG_SUCCESS); } -/** Read a molecules block. Contains chain, residue and atom data +/** + * @brief Read a molecules block. Contains chain, residue and atom data * @param tng_data is a trajectory data container. * @param block is a general block container. * @param hash_mode is an option to decide whether to use the md5 hash or not. @@ -3133,59 +2920,29 @@ static tng_function_status tng_molecules_block_len_calculate * error has occured. */ static tng_function_status tng_molecules_block_read - (tng_trajectory_t tng_data, - tng_gen_block_t block, + (const tng_trajectory_t tng_data, + const tng_gen_block_t block, const char hash_mode) { - int64_t i, j, k, l; - int len, offset = 0; + int64_t start_pos, i, j, k, l; tng_molecule_t molecule; tng_chain_t chain; tng_residue_t residue; tng_atom_t atom; tng_bond_t bond; - tng_bool same_hash; + char hash[TNG_MD5_HASH_LEN]; + md5_state_t md5_state; 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__); - } + start_pos = ftello(tng_data->input_file); /* 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: Molecules block contents corrupt. Hashes do not match. " - "%s: %d\n", - __FILE__, __LINE__); - } - } - if(tng_data->molecules) { for(i=0; in_molecules; i++) @@ -3197,19 +2954,17 @@ static tng_function_status tng_molecules_block_read tng_data->n_molecules = 0; } - memcpy(&tng_data->n_molecules, block->block_contents, - sizeof(tng_data->n_molecules)); - if(tng_data->input_endianness_swap_func_64) + if(hash_mode == TNG_USE_HASH) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &tng_data->n_molecules) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + md5_init(&md5_state); + } + + if(tng_file_input_numerical(tng_data, &tng_data->n_molecules, + sizeof(tng_data->n_molecules), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); } - offset += sizeof(tng_data->n_molecules); if(tng_data->molecules) { @@ -3250,100 +3005,55 @@ static tng_function_status tng_molecules_block_read { molecule = &tng_data->molecules[i]; - memcpy(&molecule->id, block->block_contents+offset, - sizeof(molecule->id)); - if(tng_data->input_endianness_swap_func_64) + molecule->name = 0; + + if(tng_file_input_numerical(tng_data, &molecule->id, + sizeof(molecule->id), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &molecule->id) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(molecule->id); /* fprintf(stderr, "TNG library: Read id: %"PRId64" offset: %d\n", molecule->id, offset);*/ - len = tng_min_i((int)strlen(block->block_contents+offset) + 1, TNG_MAX_STR_LEN); - molecule->name = malloc(len); - strncpy(molecule->name, block->block_contents+offset, len); - offset += len; + tng_freadstr(tng_data, &molecule->name, hash_mode, &md5_state, __LINE__); - memcpy(&molecule->quaternary_str, block->block_contents+offset, - sizeof(molecule->quaternary_str)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &molecule->quaternary_str, + sizeof(molecule->quaternary_str), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &molecule->quaternary_str) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(molecule->quaternary_str); if(!tng_data->var_num_atoms_flag) { - memcpy(&tng_data->molecule_cnt_list[i], - block->block_contents+offset, - sizeof(int64_t)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &tng_data->molecule_cnt_list[i], + sizeof(int64_t), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &tng_data->molecule_cnt_list[i]) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(int64_t); } - - memcpy(&molecule->n_chains, block->block_contents+offset, - sizeof(molecule->n_chains)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &molecule->n_chains, + sizeof(molecule->n_chains), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &molecule->n_chains) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(molecule->n_chains); - memcpy(&molecule->n_residues, block->block_contents+offset, - sizeof(molecule->n_residues)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &molecule->n_residues, + sizeof(molecule->n_residues), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &molecule->n_residues) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(molecule->n_residues); - memcpy(&molecule->n_atoms, block->block_contents+offset, - sizeof(molecule->n_atoms)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &molecule->n_atoms, + sizeof(molecule->n_atoms), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &molecule->n_atoms) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(molecule->n_atoms); tng_data->n_particles += molecule->n_atoms * tng_data->molecule_cnt_list[i]; @@ -3420,17 +3130,28 @@ static tng_function_status tng_molecules_block_read { chain->molecule = molecule; - tng_chain_data_read(tng_data, block, chain, &offset); + chain->name = 0; - chain->residues = molecule->residues; - residue = chain->residues; + tng_chain_data_read(tng_data, chain, hash_mode, &md5_state); + + if(j==0) + { + chain->residues = molecule->residues; + residue = chain->residues; + } + else + { + chain->residues = residue; + } /* Read the residues of the chain */ for(k=0; kn_residues; k++) { residue->chain = chain; - tng_residue_data_read(tng_data, block, residue, &offset); + residue->name = 0; + + tng_residue_data_read(tng_data, residue, hash_mode, &md5_state); residue->atoms_offset = atom - molecule->atoms; /* Read the atoms of the residue */ @@ -3438,7 +3159,10 @@ static tng_function_status tng_molecules_block_read { atom->residue = residue; - tng_atom_data_read(tng_data, block, atom, &offset); + atom->name = 0; + atom->atom_type = 0; + + tng_atom_data_read(tng_data,atom, hash_mode, &md5_state); atom++; } @@ -3455,7 +3179,9 @@ static tng_function_status tng_molecules_block_read { residue->chain = 0; - tng_residue_data_read(tng_data, block, residue, &offset); + residue->name = 0; + + tng_residue_data_read(tng_data, residue, hash_mode, &md5_state); residue->atoms_offset = atom - molecule->atoms; /* Read the atoms of the residue */ @@ -3463,7 +3189,7 @@ static tng_function_status tng_molecules_block_read { atom->residue = residue; - tng_atom_data_read(tng_data, block, atom, &offset); + tng_atom_data_read(tng_data, atom, hash_mode, &md5_state); atom++; } @@ -3476,26 +3202,22 @@ static tng_function_status tng_molecules_block_read { atom->residue = 0; - tng_atom_data_read(tng_data, block, atom, &offset); + atom->name = 0; + atom->atom_type = 0; + + tng_atom_data_read(tng_data, atom, hash_mode, &md5_state); atom++; } } } - memcpy(&molecule->n_bonds, block->block_contents+offset, - sizeof(molecule->n_bonds)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &molecule->n_bonds, + sizeof(molecule->n_bonds), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &molecule->n_bonds) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(molecule->n_bonds); if(molecule->n_bonds > 0) { @@ -3528,33 +3250,19 @@ static tng_function_status tng_molecules_block_read for(j=0; jn_bonds; j++) { - memcpy(&bond->from_atom_id, block->block_contents+offset, - sizeof(bond->from_atom_id)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &bond->from_atom_id, + sizeof(bond->from_atom_id), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &bond->from_atom_id) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(bond->from_atom_id); - memcpy(&bond->to_atom_id, block->block_contents+offset, - sizeof(bond->to_atom_id)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &bond->to_atom_id, + sizeof(bond->to_atom_id), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &bond->to_atom_id) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(bond->to_atom_id); bond++; } @@ -3565,10 +3273,34 @@ static tng_function_status tng_molecules_block_read } } + if(hash_mode == TNG_USE_HASH) + { + /* If there is data left in the block that the current version of the library + * cannot interpret still read that to generate the MD5 hash. */ + tng_md5_remaining_append(tng_data, block, start_pos, &md5_state); + + md5_finish(&md5_state, (md5_byte_t *)hash); + if(strncmp(block->md5_hash, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", TNG_MD5_HASH_LEN) != 0) + { + if(strncmp(block->md5_hash, hash, TNG_MD5_HASH_LEN) != 0) + { + fprintf(stderr, "TNG library: Molecules block contents corrupt. Hashes do not match. " + "%s: %d\n", __FILE__, __LINE__); + } + } + } + + else + { + /* Seek to the end of the block */ + fseeko(tng_data->input_file, start_pos + block->block_contents_size, SEEK_SET); + } + return(TNG_SUCCESS); } -/** Write a molecules block. +/** + * @brief Write a molecules block. * @param tng_data is a trajectory data container. * @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 will be generated and written. @@ -3576,17 +3308,18 @@ static tng_function_status tng_molecules_block_read * error has occured. */ static tng_function_status tng_molecules_block_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char hash_mode) { - int len = 0, name_len, offset = 0; - int64_t i, j, k, l; + int name_len; + int64_t i, j, k, l, header_file_pos, curr_file_pos; tng_molecule_t molecule; tng_chain_t chain; tng_residue_t residue; tng_atom_t atom; tng_bond_t bond; tng_gen_block_t block; + md5_state_t md5_state; if(tng_output_file_init(tng_data) != TNG_SUCCESS) { @@ -3595,7 +3328,7 @@ static tng_function_status tng_molecules_block_write tng_block_init(&block); - name_len = (int)strlen("MOLECULES"); + name_len = (unsigned int)strlen("MOLECULES"); block->name = malloc(name_len + 1); if(!block->name) @@ -3618,140 +3351,98 @@ static tng_function_status tng_molecules_block_write return(TNG_CRITICAL); } - block->block_contents = malloc(block->block_contents_size); - if(!block->block_contents) + header_file_pos = ftello(tng_data->output_file); + + if(tng_block_header_write(tng_data, block) != TNG_SUCCESS) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - block->block_contents_size, __FILE__, __LINE__); + fprintf(stderr, "TNG library: Cannot write header of file %s. %s: %d\n", + tng_data->output_file_path, __FILE__, __LINE__); tng_block_destroy(&block); return(TNG_CRITICAL); } - memcpy(block->block_contents+offset, &tng_data->n_molecules, - sizeof(tng_data->n_molecules)); - if(tng_data->output_endianness_swap_func_64) + if(hash_mode == TNG_USE_HASH) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + md5_init(&md5_state); + } + + if(tng_file_output_numerical(tng_data, &tng_data->n_molecules, + sizeof(tng_data->n_molecules), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); } - offset += sizeof(tng_data->n_molecules); for(i = 0; i < tng_data->n_molecules; i++) { molecule = &tng_data->molecules[i]; - memcpy(block->block_contents+offset, &molecule->id, - sizeof(molecule->id)); - if(tng_data->output_endianness_swap_func_64) + + if(tng_file_output_numerical(tng_data, &molecule->id, + sizeof(molecule->id), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(molecule->id); -/* fprintf(stderr, "TNG library: Wrote id: %"PRId64" offset: %d\n", molecule->id, offset); */ - len = tng_min_i((int)strlen(molecule->name) + 1, TNG_MAX_STR_LEN); - strncpy(block->block_contents + offset, molecule->name, len); - offset += len; + if(tng_fwritestr(tng_data, molecule->name, hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } - memcpy(block->block_contents+offset, &molecule->quaternary_str, - sizeof(molecule->quaternary_str)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &molecule->quaternary_str, + sizeof(molecule->quaternary_str), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(molecule->quaternary_str); if(!tng_data->var_num_atoms_flag) { - memcpy(block->block_contents+offset, - &tng_data->molecule_cnt_list[i], sizeof(int64_t)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &tng_data->molecule_cnt_list[i], + sizeof(int64_t), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(int64_t); } - memcpy(block->block_contents+offset, &molecule->n_chains, - sizeof(molecule->n_chains)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &molecule->n_chains, + sizeof(molecule->n_chains), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(molecule->n_chains); - memcpy(block->block_contents+offset, &molecule->n_residues, - sizeof(molecule->n_residues)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &molecule->n_residues, + sizeof(molecule->n_residues), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(molecule->n_residues); - memcpy(block->block_contents+offset, &molecule->n_atoms, - sizeof(molecule->n_atoms)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &molecule->n_atoms, + sizeof(molecule->n_atoms), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(molecule->n_atoms); if(molecule->n_chains > 0) { chain = molecule->chains; for(j = 0; j < molecule->n_chains; j++) { - tng_chain_data_write(tng_data, block, chain, &offset); + tng_chain_data_write(tng_data, chain, hash_mode, &md5_state); residue = chain->residues; for(k = 0; k < chain->n_residues; k++) { - tng_residue_data_write(tng_data, block, residue, &offset); + tng_residue_data_write(tng_data, residue, hash_mode, &md5_state); atom = molecule->atoms + residue->atoms_offset; for(l = 0; l < residue->n_atoms; l++) { - tng_atom_data_write(tng_data, block, atom, &offset); + tng_atom_data_write(tng_data, atom, hash_mode, &md5_state); atom++; } @@ -3767,12 +3458,12 @@ static tng_function_status tng_molecules_block_write residue = molecule->residues; for(k = 0; k < molecule->n_residues; k++) { - tng_residue_data_write(tng_data, block, residue, &offset); + tng_residue_data_write(tng_data, residue, hash_mode, &md5_state); atom = molecule->atoms + residue->atoms_offset; for(l = 0; l < residue->n_atoms; l++) { - tng_atom_data_write(tng_data, block, atom, &offset); + tng_atom_data_write(tng_data, atom, hash_mode, &md5_state); atom++; } @@ -3784,77 +3475,53 @@ static tng_function_status tng_molecules_block_write atom = molecule->atoms; for(l = 0; l < molecule->n_atoms; l++) { - tng_atom_data_write(tng_data, block, atom, &offset); + tng_atom_data_write(tng_data, atom, hash_mode, &md5_state); atom++; } } } - memcpy(block->block_contents+offset, &molecule->n_bonds, - sizeof(molecule->n_bonds)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &molecule->n_bonds, + sizeof(molecule->n_bonds), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(molecule->n_bonds); bond = molecule->bonds; for(j = 0; j < molecule->n_bonds; j++) { - memcpy(block->block_contents+offset, &bond->from_atom_id, - sizeof(bond->from_atom_id)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &bond->from_atom_id, + sizeof(bond->from_atom_id), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(bond->from_atom_id); - memcpy(block->block_contents+offset, &bond->to_atom_id, - sizeof(bond->to_atom_id)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &bond->to_atom_id, + sizeof(bond->to_atom_id), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(bond->to_atom_id); bond++; } } - - if(tng_block_header_write(tng_data, block, hash_mode) != TNG_SUCCESS) + if(hash_mode == TNG_USE_HASH) { - fprintf(stderr, "TNG library: Cannot write header of file %s. %s: %d\n", - tng_data->output_file_path, __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); - } - - if(fwrite(block->block_contents, block->block_contents_size, 1, - tng_data->output_file) != 1) - { - fprintf(stderr, "TNG library: Could not write all block data. %s: %d\n", - __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); + md5_finish(&md5_state, (md5_byte_t *)block->md5_hash); + curr_file_pos = ftello(tng_data->output_file); + fseeko(tng_data->output_file, header_file_pos + + 3 * sizeof(int64_t), SEEK_SET); + if(fwrite(block->md5_hash, TNG_MD5_HASH_LEN, 1, tng_data->output_file) != 1) + { + fprintf(stderr, "TNG library: Could not write MD5 hash. %s: %d\n", __FILE__, + __LINE__); + return(TNG_CRITICAL); + } + fseeko(tng_data->output_file, curr_file_pos, SEEK_SET); } tng_block_destroy(&block); @@ -3876,7 +3543,8 @@ static tng_function_status tng_frame_set_block_len_calculate return(TNG_SUCCESS); } -/** Read a frame set block. Update tng_data->current_trajectory_frame_set +/** + * @brief Read a frame set block. Update tng_data->current_trajectory_frame_set * @param tng_data is a trajectory data container. * @param block is a general block container. * @param hash_mode is an option to decide whether to use the md5 hash or not. @@ -3890,99 +3558,45 @@ static tng_function_status tng_frame_set_block_read tng_gen_block_t block, const char hash_mode) { - int offset = 0; - int64_t file_pos, i, prev_n_particles; - tng_bool same_hash; + int64_t file_pos, start_pos, i, prev_n_particles; tng_trajectory_frame_set_t frame_set = &tng_data->current_trajectory_frame_set; + char hash[TNG_MD5_HASH_LEN]; + md5_state_t md5_state; 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); - } + start_pos = ftello(tng_data->input_file); /* FIXME: Does not check if the size of the contents matches the expected * size or if the contents can be read. */ - file_pos = (int64_t)ftello(tng_data->input_file) - - (block->block_contents_size + block->header_contents_size); - - if(hash_mode == TNG_USE_HASH) - { - tng_md5_hash_match_verify(block, &same_hash); - if(same_hash != TNG_TRUE) - { - fprintf(stderr, "TNG library: Frame set block contents corrupt. File pos %"PRId64" Hashes do not match. " - "%s: %d\n", - file_pos, __FILE__, __LINE__); - /* return(TNG_FAILURE); */ - } - } + file_pos = start_pos - block->header_contents_size; tng_data->current_trajectory_frame_set_input_file_pos = file_pos; tng_frame_set_particle_mapping_free(tng_data); - if(tng_data->first_trajectory_frame_set_input_file_pos <= 0) - { - tng_data->first_trajectory_frame_set_input_file_pos = file_pos; - } - /* FIXME: Should check the frame number instead of the file_pos, in case - * frame sets are not in order */ - if(tng_data->last_trajectory_frame_set_input_file_pos < file_pos) + if(hash_mode == TNG_USE_HASH) { - tng_data->last_trajectory_frame_set_input_file_pos = file_pos; + md5_init(&md5_state); } - - memcpy(&frame_set->first_frame, block->block_contents, - sizeof(frame_set->first_frame)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &frame_set->first_frame, + sizeof(frame_set->first_frame), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &frame_set->first_frame) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(frame_set->first_frame); - memcpy(&frame_set->n_frames, block->block_contents + offset, - sizeof(frame_set->n_frames)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &frame_set->n_frames, + sizeof(frame_set->n_frames), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &frame_set->n_frames) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(frame_set->n_frames); if(tng_data->var_num_atoms_flag) { @@ -4005,20 +3619,13 @@ static tng_function_status tng_frame_set_block_read } for(i = 0; i < tng_data->n_molecules; i++) { - memcpy(&frame_set->molecule_cnt_list[i], - block->block_contents + offset, - sizeof(int64_t)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &frame_set->molecule_cnt_list[i], + sizeof(int64_t), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &frame_set->molecule_cnt_list[i]) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(int64_t); + frame_set->n_particles += tng_data->molecules[i].n_atoms * frame_set->molecule_cnt_list[i]; } @@ -4028,125 +3635,62 @@ static tng_function_status tng_frame_set_block_read } } - memcpy(&frame_set->next_frame_set_file_pos, - block->block_contents + offset, - sizeof(frame_set->next_frame_set_file_pos)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &frame_set->next_frame_set_file_pos, + sizeof(frame_set->next_frame_set_file_pos), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &frame_set->next_frame_set_file_pos) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(frame_set->next_frame_set_file_pos); - memcpy(&frame_set->prev_frame_set_file_pos, - block->block_contents + offset, - sizeof(frame_set->prev_frame_set_file_pos)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &frame_set->prev_frame_set_file_pos, + sizeof(frame_set->prev_frame_set_file_pos), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &frame_set->prev_frame_set_file_pos) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(frame_set->prev_frame_set_file_pos); - memcpy(&frame_set->medium_stride_next_frame_set_file_pos, - block->block_contents + offset, - sizeof(frame_set->medium_stride_next_frame_set_file_pos)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &frame_set->medium_stride_next_frame_set_file_pos, + sizeof(frame_set->medium_stride_next_frame_set_file_pos), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &frame_set->medium_stride_next_frame_set_file_pos) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(frame_set->medium_stride_next_frame_set_file_pos); - memcpy(&frame_set->medium_stride_prev_frame_set_file_pos, - block->block_contents + offset, - sizeof(frame_set->medium_stride_prev_frame_set_file_pos)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &frame_set->medium_stride_prev_frame_set_file_pos, + sizeof(frame_set->medium_stride_prev_frame_set_file_pos), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &frame_set->medium_stride_prev_frame_set_file_pos) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(frame_set->medium_stride_prev_frame_set_file_pos); - memcpy(&frame_set->long_stride_next_frame_set_file_pos, - block->block_contents + offset, - sizeof(frame_set->long_stride_next_frame_set_file_pos)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &frame_set->long_stride_next_frame_set_file_pos, + sizeof(frame_set->long_stride_next_frame_set_file_pos), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &frame_set->long_stride_next_frame_set_file_pos) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(frame_set->long_stride_next_frame_set_file_pos); - memcpy(&frame_set->long_stride_prev_frame_set_file_pos, - block->block_contents + offset, - sizeof(frame_set->long_stride_prev_frame_set_file_pos)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &frame_set->long_stride_prev_frame_set_file_pos, + sizeof(frame_set->long_stride_prev_frame_set_file_pos), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &frame_set->long_stride_prev_frame_set_file_pos) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(frame_set->long_stride_prev_frame_set_file_pos); if(block->block_version >= 3) { - memcpy(&frame_set->first_frame_time, - block->block_contents + offset, - sizeof(frame_set->first_frame_time)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &frame_set->first_frame_time, + sizeof(frame_set->first_frame_time), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - (int64_t *)&frame_set->first_frame_time) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(frame_set->first_frame_time); - memcpy(&tng_data->time_per_frame, - block->block_contents + offset, - sizeof(tng_data->time_per_frame)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &tng_data->time_per_frame, + sizeof(tng_data->time_per_frame), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - (int64_t *)&tng_data->time_per_frame) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } } else @@ -4155,6 +3699,28 @@ static tng_function_status tng_frame_set_block_read tng_data->time_per_frame = -1; } + if(hash_mode == TNG_USE_HASH) + { + /* If there is data left in the block that the current version of the library + * cannot interpret still read that to generate the MD5 hash. */ + tng_md5_remaining_append(tng_data, block, start_pos, &md5_state); + + md5_finish(&md5_state, (md5_byte_t *)hash); + if(strncmp(block->md5_hash, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", TNG_MD5_HASH_LEN) != 0) + { + if(strncmp(block->md5_hash, hash, TNG_MD5_HASH_LEN) != 0) + { + fprintf(stderr, "TNG library: Frame set block contents corrupt (first frame %"PRId64"). Hashes do not match. " + "%s: %d\n", frame_set->first_frame, __FILE__, __LINE__); + } + } + } + else + { + /* Seek to the end of the block */ + fseeko(tng_data->input_file, start_pos + block->block_contents_size, SEEK_SET); + } + /* If the output file and the input files are the same the number of * frames in the file are the same number as has just been read. * This is updated here to later on see if there have been new frames @@ -4167,7 +3733,8 @@ static tng_function_status tng_frame_set_block_read return(TNG_SUCCESS); } -/** Write tng_data->current_trajectory_frame_set to file +/** + * @brief Write tng_data->current_trajectory_frame_set to file * @param tng_data is a trajectory data container. * @param block is a general block container. * @param hash_mode is an option to decide whether to use the md5 hash or not. @@ -4176,23 +3743,23 @@ static tng_function_status tng_frame_set_block_read * error has occured. */ static tng_function_status tng_frame_set_block_write - (tng_trajectory_t tng_data, - tng_gen_block_t block, + (const tng_trajectory_t tng_data, + const tng_gen_block_t block, const char hash_mode) { char *temp_name; - int64_t i; - int offset = 0; + int64_t i, header_file_pos, curr_file_pos; unsigned int name_len; tng_trajectory_frame_set_t frame_set = &tng_data->current_trajectory_frame_set; + md5_state_t md5_state; if(tng_output_file_init(tng_data) != TNG_SUCCESS) { return(TNG_CRITICAL); } - name_len = (int)strlen("TRAJECTORY FRAME SET"); + name_len = (unsigned int)strlen("TRAJECTORY FRAME SET"); if(!block->name || strlen(block->name) < name_len) { @@ -4218,197 +3785,114 @@ static tng_function_status tng_frame_set_block_write return(TNG_CRITICAL); } - if(block->block_contents) - { - free(block->block_contents); - } - block->block_contents = malloc(block->block_contents_size); - if(!block->block_contents) + header_file_pos = ftello(tng_data->output_file); + + if(tng_block_header_write(tng_data, block) != TNG_SUCCESS) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - block->block_contents_size, __FILE__, __LINE__); + fprintf(stderr, "TNG library: Cannot write header of file %s. %s: %d\n", + tng_data->output_file_path, __FILE__, __LINE__); return(TNG_CRITICAL); } - memcpy(block->block_contents, &frame_set->first_frame, - sizeof(frame_set->first_frame)); - if(tng_data->output_endianness_swap_func_64) + if(hash_mode == TNG_USE_HASH) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + md5_init(&md5_state); + } + if(tng_file_output_numerical(tng_data, &frame_set->first_frame, + sizeof(frame_set->first_frame), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); } - offset += sizeof(frame_set->first_frame); - memcpy(block->block_contents+offset, &frame_set->n_frames, - sizeof(frame_set->n_frames)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &frame_set->n_frames, + sizeof(frame_set->n_frames), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(frame_set->n_frames); if(tng_data->var_num_atoms_flag) { for(i = 0; i < tng_data->n_molecules; i++) { - memcpy(block->block_contents+offset, - &frame_set->molecule_cnt_list[i], - sizeof(int64_t)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &frame_set->molecule_cnt_list[i], + sizeof(int64_t), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(int64_t); - } - } - - - memcpy(block->block_contents+offset, &frame_set->next_frame_set_file_pos, - sizeof(frame_set->next_frame_set_file_pos)); - if(tng_data->output_endianness_swap_func_64) - { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); } } - offset += sizeof(frame_set->next_frame_set_file_pos); - memcpy(block->block_contents+offset, &frame_set->prev_frame_set_file_pos, - sizeof(frame_set->prev_frame_set_file_pos)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &frame_set->next_frame_set_file_pos, + sizeof(frame_set->next_frame_set_file_pos), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(frame_set->prev_frame_set_file_pos); - memcpy(block->block_contents+offset, - &frame_set->medium_stride_next_frame_set_file_pos, - sizeof(frame_set->medium_stride_next_frame_set_file_pos)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &frame_set->prev_frame_set_file_pos, + sizeof(frame_set->prev_frame_set_file_pos), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(frame_set->medium_stride_next_frame_set_file_pos); - memcpy(block->block_contents+offset, - &frame_set->medium_stride_prev_frame_set_file_pos, - sizeof(frame_set->medium_stride_prev_frame_set_file_pos)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &frame_set->medium_stride_next_frame_set_file_pos, + sizeof(frame_set->medium_stride_next_frame_set_file_pos), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(frame_set->medium_stride_prev_frame_set_file_pos); - memcpy(block->block_contents+offset, - &frame_set->long_stride_next_frame_set_file_pos, - sizeof(frame_set->long_stride_next_frame_set_file_pos)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &frame_set->medium_stride_prev_frame_set_file_pos, + sizeof(frame_set->medium_stride_prev_frame_set_file_pos), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(frame_set->long_stride_next_frame_set_file_pos); - memcpy(block->block_contents+offset, - &frame_set->long_stride_prev_frame_set_file_pos, - sizeof(frame_set->long_stride_prev_frame_set_file_pos)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &frame_set->long_stride_next_frame_set_file_pos, + sizeof(frame_set->long_stride_next_frame_set_file_pos), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(frame_set->long_stride_prev_frame_set_file_pos); - memcpy(block->block_contents+offset, - &frame_set->first_frame_time, - sizeof(frame_set->first_frame_time)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &frame_set->long_stride_prev_frame_set_file_pos, + sizeof(frame_set->long_stride_prev_frame_set_file_pos), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(frame_set->first_frame_time); - memcpy(block->block_contents+offset, - &tng_data->time_per_frame, - sizeof(tng_data->time_per_frame)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &frame_set->first_frame_time, + sizeof(frame_set->first_frame_time), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - if(tng_block_header_write(tng_data, block, hash_mode) != TNG_SUCCESS) + if(tng_file_output_numerical(tng_data, &tng_data->time_per_frame, + sizeof(tng_data->time_per_frame), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot write header of file %s. %s: %d\n", - tng_data->output_file_path, __FILE__, __LINE__); return(TNG_CRITICAL); } - - if(fwrite(block->block_contents, block->block_contents_size, 1, - tng_data->output_file) != 1) + if(hash_mode == TNG_USE_HASH) { - fprintf(stderr, "TNG library: Could not write all block data. %s: %d\n", __FILE__, __LINE__); - return(TNG_CRITICAL); + md5_finish(&md5_state, (md5_byte_t *)block->md5_hash); + curr_file_pos = ftello(tng_data->output_file); + fseeko(tng_data->output_file, header_file_pos + + 3 * sizeof(int64_t), SEEK_SET); + if(fwrite(block->md5_hash, TNG_MD5_HASH_LEN, 1, tng_data->output_file) != 1) + { + fprintf(stderr, "TNG library: Could not write MD5 hash. %s: %d\n", __FILE__, + __LINE__); + return(TNG_CRITICAL); + } + fseeko(tng_data->output_file, curr_file_pos, SEEK_SET); } return(TNG_SUCCESS); @@ -4425,7 +3909,8 @@ static tng_function_status tng_trajectory_mapping_block_len_calculate return(TNG_SUCCESS); } -/** Read an atom mappings block (translating between real atom indexes and how +/** + * @brief Read an atom mappings block (translating between real atom indexes and how * the atom info is written in this frame set). * @param tng_data is a trajectory data container. * @param block is a general block container. @@ -4436,60 +3921,27 @@ static tng_function_status tng_trajectory_mapping_block_len_calculate * error has occured. */ static tng_function_status tng_trajectory_mapping_block_read - (tng_trajectory_t tng_data, - tng_gen_block_t block, + (const tng_trajectory_t tng_data, + const tng_gen_block_t block, const char hash_mode) { - int64_t i; - int offset = 0; - tng_bool same_hash; + int64_t start_pos, i; tng_trajectory_frame_set_t frame_set = &tng_data->current_trajectory_frame_set; - tng_particle_mapping_t mapping, mappings; + char hash[TNG_MD5_HASH_LEN]; + md5_state_t md5_state; 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); - } + start_pos = ftello(tng_data->input_file); /* 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: Particle mapping block contents corrupt. Hashes do not match. " - "%s: %d\n", - __FILE__, __LINE__); - /* return(TNG_FAILURE); */ - } - } - frame_set->n_mapping_blocks++; mappings = realloc(frame_set->mappings, sizeof(struct tng_particle_mapping) * @@ -4506,33 +3958,24 @@ static tng_function_status tng_trajectory_mapping_block_read mapping = &mappings[frame_set->n_mapping_blocks - 1]; - memcpy(&mapping->num_first_particle, block->block_contents+offset, - sizeof(mapping->num_first_particle)); - if(tng_data->input_endianness_swap_func_64) + if(hash_mode == TNG_USE_HASH) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &mapping->num_first_particle) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + md5_init(&md5_state); } - offset += sizeof(mapping->num_first_particle); - memcpy(&mapping->n_particles, block->block_contents+offset, - sizeof(mapping->n_particles)); - if(tng_data->input_endianness_swap_func_64) + if(tng_file_input_numerical(tng_data, &mapping->num_first_particle, + sizeof(mapping->num_first_particle), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->input_endianness_swap_func_64(tng_data, - &mapping->n_particles) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); + } + + if(tng_file_input_numerical(tng_data, &mapping->n_particles, + sizeof(mapping->n_particles), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); } - offset += sizeof(mapping->n_particles); mapping->real_particle_numbers = malloc(mapping->n_particles * sizeof(int64_t)); @@ -4549,31 +3992,56 @@ static tng_function_status tng_trajectory_mapping_block_read { for(i = 0; i < mapping->n_particles; i++) { - memcpy(&mapping->real_particle_numbers[i], - block->block_contents + offset, - sizeof(int64_t)); - if(tng_data->input_endianness_swap_func_64(tng_data, - &mapping->real_particle_numbers[i]) - != TNG_SUCCESS) + if(tng_file_input_numerical(tng_data, &mapping->real_particle_numbers[i], + sizeof(int64_t), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); + return(TNG_CRITICAL); } - offset += sizeof(int64_t); } } /* Otherwise the data can be read all at once */ else { - memcpy(mapping->real_particle_numbers, block->block_contents + offset, - mapping->n_particles * sizeof(int64_t)); + if(fread(mapping->real_particle_numbers, mapping->n_particles * sizeof(int64_t), + 1, tng_data->input_file) == 0) + { + fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, __LINE__); + return(TNG_CRITICAL); + } + if(hash_mode == TNG_USE_HASH) + { + md5_append(&md5_state, (md5_byte_t *)mapping->real_particle_numbers, mapping->n_particles * sizeof(int64_t)); + } } + if(hash_mode == TNG_USE_HASH) + { + /* If there is data left in the block that the current version of the library + * cannot interpret still read that to generate the MD5 hash. */ + tng_md5_remaining_append(tng_data, block, start_pos, &md5_state); + + md5_finish(&md5_state, (md5_byte_t *)hash); + if(strncmp(block->md5_hash, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", TNG_MD5_HASH_LEN) != 0) + { + if(strncmp(block->md5_hash, hash, TNG_MD5_HASH_LEN) != 0) + { + fprintf(stderr, "TNG library: Particle mapping block contents corrupt. Hashes do not match. " + "%s: %d\n", __FILE__, __LINE__); + } + } + } + else + { + /* Seek to the end of the block */ + fseeko(tng_data->input_file, start_pos + block->block_contents_size, SEEK_SET); + } return(TNG_SUCCESS); } -/** Write the atom mappings of the current trajectory frame set +/** + * @brief Write the atom mappings of the current trajectory frame set * @param tng_data is a trajectory data container. * @param block is a general block container. * @param mapping_block_nr is the index of the mapping block to write. @@ -4583,14 +4051,16 @@ static tng_function_status tng_trajectory_mapping_block_read * has occurred or TNG_CRITICAL (2) if a major error has occured. */ static tng_function_status tng_trajectory_mapping_block_write - (tng_trajectory_t tng_data, - tng_gen_block_t block, - int mapping_block_nr, + (const tng_trajectory_t tng_data, + const tng_gen_block_t block, + const int mapping_block_nr, const char hash_mode) { + int64_t header_file_pos, curr_file_pos; char *temp_name; - int i, offset = 0; + int i; unsigned int name_len; + md5_state_t md5_state; tng_particle_mapping_t mapping = &tng_data->current_trajectory_frame_set.mappings[mapping_block_nr]; @@ -4607,7 +4077,7 @@ static tng_function_status tng_trajectory_mapping_block_write return(TNG_CRITICAL); } - name_len = (int)strlen("PARTICLE MAPPING"); + name_len = (unsigned int)strlen("PARTICLE MAPPING"); if(!block->name || strlen(block->name) < name_len) { @@ -4635,87 +4105,81 @@ static tng_function_status tng_trajectory_mapping_block_write return(TNG_CRITICAL); } - if(block->block_contents) - { - free(block->block_contents); - } - block->block_contents = malloc(block->block_contents_size); - if(!block->block_contents) + header_file_pos = ftello(tng_data->output_file); + + if(tng_block_header_write(tng_data, block) != TNG_SUCCESS) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - block->block_contents_size, __FILE__, __LINE__); + fprintf(stderr, "TNG library: Cannot write header of file %s. %s: %d\n", + tng_data->output_file_path, __FILE__, __LINE__); return(TNG_CRITICAL); } - memcpy(block->block_contents, &mapping->num_first_particle, - sizeof(mapping->num_first_particle)); - if(tng_data->output_endianness_swap_func_64) + if(hash_mode == TNG_USE_HASH) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + md5_init(&md5_state); + } + if(tng_file_output_numerical(tng_data, &mapping->num_first_particle, + sizeof(mapping->num_first_particle), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); } - offset += sizeof(mapping->num_first_particle); - memcpy(block->block_contents+offset, &mapping->n_particles, - sizeof(mapping->n_particles)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &mapping->n_particles, + sizeof(mapping->n_particles), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(mapping->n_particles); if(tng_data->output_endianness_swap_func_64) { for(i = 0; i < mapping->n_particles; i++) { - memcpy(block->block_contents+offset, &mapping->real_particle_numbers[i], - sizeof(int64_t)); - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) + if(tng_file_output_numerical(tng_data, &mapping->real_particle_numbers[i], + sizeof(int64_t), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); + return(TNG_CRITICAL); } - offset += sizeof(int64_t); } } else { - memcpy(block->block_contents+offset, mapping->real_particle_numbers, - mapping->n_particles * sizeof(int64_t)); - } - - - if(tng_block_header_write(tng_data, block, hash_mode) != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot write header of file %s. %s: %d\n", - tng_data->output_file_path, __FILE__, __LINE__); - return(TNG_CRITICAL); + if(fwrite(mapping->real_particle_numbers, + mapping->n_particles * sizeof(int64_t), + 1, tng_data->output_file) != 1) + { + fprintf(stderr, "TNG library: Could not write block data. %s: %d\n", __FILE__, __LINE__); + return(TNG_CRITICAL); + } + if(hash_mode == TNG_USE_HASH) + { + md5_append(&md5_state, (md5_byte_t *)mapping->real_particle_numbers, + mapping->n_particles * sizeof(int64_t)); + } } - if(fwrite(block->block_contents, block->block_contents_size, 1, - tng_data->output_file) != 1) + if(hash_mode == TNG_USE_HASH) { - fprintf(stderr, "TNG library: Could not write all block data. %s: %d\n", __FILE__, __LINE__); - return(TNG_CRITICAL); + md5_finish(&md5_state, (md5_byte_t *)block->md5_hash); + curr_file_pos = ftello(tng_data->output_file); + fseeko(tng_data->output_file, header_file_pos + + 3 * sizeof(int64_t), SEEK_SET); + if(fwrite(block->md5_hash, TNG_MD5_HASH_LEN, 1, tng_data->output_file) != 1) + { + fprintf(stderr, "TNG library: Could not write MD5 hash. %s: %d\n", __FILE__, + __LINE__); + return(TNG_CRITICAL); + } + fseeko(tng_data->output_file, curr_file_pos, SEEK_SET); } return(TNG_SUCCESS); } -/** Prepare a block for storing particle data +/** + * @brief Prepare a block for storing particle data * @param tng_data is a trajectory data container. * @param block_type_flag specifies if this is a trajectory block or a * non-trajectory block. (TNG_TRAJECTORY_BLOCK or TNG_NON_TRAJECTORY_BLOCK) @@ -4723,24 +4187,24 @@ static tng_function_status tng_trajectory_mapping_block_write * error has occured. */ static tng_function_status tng_particle_data_block_create - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char block_type_flag) { tng_trajectory_frame_set_t frame_set = &tng_data->current_trajectory_frame_set; - tng_particle_data_t data; + tng_data_t data; if(block_type_flag == TNG_TRAJECTORY_BLOCK) { frame_set->n_particle_data_blocks++; data = realloc(frame_set->tr_particle_data, - sizeof(struct tng_particle_data) * + sizeof(struct tng_data) * frame_set->n_particle_data_blocks); if(!data) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n", - sizeof(struct tng_particle_data) * + fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n", + sizeof(struct tng_data) * frame_set->n_particle_data_blocks, __FILE__, __LINE__); free(frame_set->tr_particle_data); @@ -4753,12 +4217,12 @@ static tng_function_status tng_particle_data_block_create { tng_data->n_particle_data_blocks++; data = realloc(tng_data->non_tr_particle_data, - sizeof(struct tng_particle_data) * + sizeof(struct tng_data) * tng_data->n_particle_data_blocks); if(!data) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n", - sizeof(struct tng_particle_data) * + fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n", + sizeof(struct tng_data) * tng_data->n_particle_data_blocks, __FILE__, __LINE__); free(tng_data->non_tr_particle_data); @@ -4771,18 +4235,19 @@ static tng_function_status tng_particle_data_block_create return(TNG_SUCCESS); } -static tng_function_status tng_compress(tng_trajectory_t tng_data, - tng_gen_block_t block, +static tng_function_status tng_compress(const tng_trajectory_t tng_data, + const tng_gen_block_t block, const int64_t n_frames, const int64_t n_particles, const char type, - void *start_pos) + char **data, + int64_t *new_len) { int nalgo; - int new_len; + int compressed_len; int *alt_algo = 0; - char *dest, *temp, *temp_data_contents; - int64_t algo_find_n_frames, compressed_len, offset; + char *dest; + int64_t algo_find_n_frames = -1; float f_precision; double d_precision; @@ -4809,17 +4274,6 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data, f_precision = 1/(float)tng_data->compression_precision; d_precision = 1/tng_data->compression_precision; - compressed_len = block->block_contents_size - (int64_t)((char *)start_pos - (char *)block->block_contents); - temp_data_contents = malloc(compressed_len); - if(!temp_data_contents) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - compressed_len, __FILE__, __LINE__); - return(TNG_CRITICAL); - } - - memcpy(temp_data_contents, (char *)start_pos, compressed_len); - if(block->id == TNG_TRAJ_POSITIONS) { /* If there is only one frame in this frame set and there might be more @@ -4828,28 +4282,61 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data, if(n_frames == 1 && tng_data->frame_set_n_frames > 1) { nalgo = tng_compress_nalgo(); - alt_algo=malloc(nalgo * sizeof *tng_data->compress_algo_pos); + alt_algo = malloc(nalgo * sizeof *tng_data->compress_algo_pos); + + /* If we have already determined the initial coding and + * initial coding parameter do not determine them again. */ + if(tng_data->compress_algo_pos) + { + alt_algo[0] = tng_data->compress_algo_pos[0]; + alt_algo[1] = tng_data->compress_algo_pos[1]; + alt_algo[2] = tng_data->compress_algo_pos[2]; + alt_algo[3] = tng_data->compress_algo_pos[3]; + } + else + { + alt_algo[0] = -1; + alt_algo[1] = -1; + alt_algo[2] = -1; + alt_algo[3] = -1; + } + + /* If the initial coding and initial coding parameter are -1 + * they will be determined in tng_compress_pos/_float/. */ if(type == TNG_FLOAT_DATA) { - dest = tng_compress_pos_float_find_algo((float *)temp_data_contents, (int)n_particles, - (int)n_frames, - f_precision, - 0, alt_algo, - &new_len); + dest = tng_compress_pos_float((float *)*data, (int)n_particles, + (int)n_frames, + f_precision, + 0, alt_algo, + &compressed_len); } else { - dest = tng_compress_pos_find_algo((double *)temp_data_contents, (int)n_particles, - (int)n_frames, - d_precision, - 0, alt_algo, - &new_len); + dest = tng_compress_pos((double *)*data, (int)n_particles, + (int)n_frames, + d_precision, + 0, alt_algo, + &compressed_len); + } + /* If there had been no algorithm determined before keep the initial coding + * and initial coding parameter so that they won't have to be determined again. */ + if(!tng_data->compress_algo_pos) + { + nalgo = tng_compress_nalgo(); + tng_data->compress_algo_pos=malloc(nalgo * + sizeof *tng_data->compress_algo_pos); + tng_data->compress_algo_pos[0] = alt_algo[0]; + tng_data->compress_algo_pos[1] = alt_algo[1]; + tng_data->compress_algo_pos[2] = -1; + tng_data->compress_algo_pos[3] = -1; } } - else if(!tng_data->compress_algo_pos) + else if(!tng_data->compress_algo_pos || tng_data->compress_algo_pos[2] == -1 || + tng_data->compress_algo_pos[2] == -1) { - if(n_frames > 10) + if(n_frames > 6) { algo_find_n_frames = 5; } @@ -4858,43 +4345,54 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data, algo_find_n_frames = n_frames; } - nalgo = tng_compress_nalgo(); - tng_data->compress_algo_pos=malloc(nalgo * - sizeof *tng_data->compress_algo_pos); + /* If the algorithm parameters are -1 they will be determined during the + * compression. */ + if(!tng_data->compress_algo_pos) + { + nalgo = tng_compress_nalgo(); + tng_data->compress_algo_pos=malloc(nalgo * + sizeof *tng_data->compress_algo_pos); + tng_data->compress_algo_pos[0] = -1; + tng_data->compress_algo_pos[1] = -1; + tng_data->compress_algo_pos[2] = -1; + tng_data->compress_algo_pos[3] = -1; + } if(type == TNG_FLOAT_DATA) { - dest = tng_compress_pos_float_find_algo((float *)temp_data_contents, (int)n_particles, - (int)algo_find_n_frames, - f_precision, - 0, tng_data-> - compress_algo_pos, - &new_len); + dest = tng_compress_pos_float((float *)*data, (int)n_particles, + (int)algo_find_n_frames, + f_precision, + 0, tng_data-> + compress_algo_pos, + &compressed_len); if(algo_find_n_frames < n_frames) { - dest = tng_compress_pos_float((float *)temp_data_contents, (int)n_particles, + free(dest); + dest = tng_compress_pos_float((float *)*data, (int)n_particles, (int)n_frames, f_precision, 0, tng_data->compress_algo_pos, - &new_len); + &compressed_len); } } else { - dest = tng_compress_pos_find_algo((double *)temp_data_contents, (int)n_particles, - (int)algo_find_n_frames, - d_precision, - 0, tng_data-> - compress_algo_pos, - &new_len); + dest = tng_compress_pos((double *)*data, (int)n_particles, + (int)algo_find_n_frames, + d_precision, + 0, tng_data-> + compress_algo_pos, + &compressed_len); if(algo_find_n_frames < n_frames) { - dest = tng_compress_pos((double *)temp_data_contents, (int)n_particles, + free(dest); + dest = tng_compress_pos((double *)*data, (int)n_particles, (int)n_frames, d_precision, 0, tng_data->compress_algo_pos, - &new_len); + &compressed_len); } } } @@ -4902,18 +4400,18 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data, { if(type == TNG_FLOAT_DATA) { - dest = tng_compress_pos_float((float *)temp_data_contents, (int)n_particles, + dest = tng_compress_pos_float((float *)*data, (int)n_particles, (int)n_frames, f_precision, 0, - tng_data->compress_algo_pos, &new_len); + tng_data->compress_algo_pos, &compressed_len); } else { - dest = tng_compress_pos((double *)temp_data_contents, (int)n_particles, + dest = tng_compress_pos((double *)*data, (int)n_particles, (int)n_frames, d_precision, 0, tng_data->compress_algo_pos, - &new_len); + &compressed_len); } } } @@ -4926,27 +4424,60 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data, { nalgo = tng_compress_nalgo(); alt_algo=malloc(nalgo * sizeof *tng_data->compress_algo_vel); + + /* If we have already determined the initial coding and + * initial coding parameter do not determine them again. */ + if(tng_data->compress_algo_vel) + { + alt_algo[0] = tng_data->compress_algo_vel[0]; + alt_algo[1] = tng_data->compress_algo_vel[1]; + alt_algo[2] = tng_data->compress_algo_vel[2]; + alt_algo[3] = tng_data->compress_algo_vel[3]; + } + else + { + alt_algo[0] = -1; + alt_algo[1] = -1; + alt_algo[2] = -1; + alt_algo[3] = -1; + } + + /* If the initial coding and initial coding parameter are -1 + * they will be determined in tng_compress_pos/_float/. */ if(type == TNG_FLOAT_DATA) { - dest = tng_compress_vel_float_find_algo((float *)temp_data_contents, (int)n_particles, - (int)n_frames, - f_precision, - 0, alt_algo, - &new_len); + dest = tng_compress_vel_float((float *)*data, (int)n_particles, + (int)n_frames, + f_precision, + 0, alt_algo, + &compressed_len); } else { - dest = tng_compress_vel_find_algo((double *)temp_data_contents, (int)n_particles, - (int)n_frames, - d_precision, - 0, alt_algo, - &new_len); + dest = tng_compress_vel((double *)*data, (int)n_particles, + (int)n_frames, + d_precision, + 0, alt_algo, + &compressed_len); + } + /* If there had been no algorithm determined before keep the initial coding + * and initial coding parameter so that they won't have to be determined again. */ + if(!tng_data->compress_algo_vel) + { + nalgo = tng_compress_nalgo(); + tng_data->compress_algo_vel=malloc(nalgo * + sizeof *tng_data->compress_algo_vel); + tng_data->compress_algo_vel[0] = alt_algo[0]; + tng_data->compress_algo_vel[1] = alt_algo[1]; + tng_data->compress_algo_vel[2] = -1; + tng_data->compress_algo_vel[3] = -1; } } - else if(!tng_data->compress_algo_vel) + else if(!tng_data->compress_algo_vel || tng_data->compress_algo_vel[2] == -1 || + tng_data->compress_algo_vel[2] == -1) { - if(n_frames > 10) + if(n_frames > 6) { algo_find_n_frames = 5; } @@ -4955,42 +4486,52 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data, algo_find_n_frames = n_frames; } - nalgo = tng_compress_nalgo(); - tng_data->compress_algo_vel=malloc(nalgo * - sizeof *tng_data->compress_algo_vel); - + /* If the algorithm parameters are -1 they will be determined during the + * compression. */ + if(!tng_data->compress_algo_vel) + { + nalgo = tng_compress_nalgo(); + tng_data->compress_algo_vel=malloc(nalgo * + sizeof *tng_data->compress_algo_vel); + tng_data->compress_algo_vel[0] = -1; + tng_data->compress_algo_vel[1] = -1; + tng_data->compress_algo_vel[2] = -1; + tng_data->compress_algo_vel[3] = -1; + } if(type == TNG_FLOAT_DATA) { - dest = tng_compress_vel_float_find_algo((float *)temp_data_contents, (int)n_particles, - (int)algo_find_n_frames, - f_precision, - 0, tng_data-> - compress_algo_vel, - &new_len); + dest = tng_compress_vel_float((float *)*data, (int)n_particles, + (int)algo_find_n_frames, + f_precision, + 0, tng_data-> + compress_algo_vel, + &compressed_len); if(algo_find_n_frames < n_frames) { - dest = tng_compress_vel_float((float *)temp_data_contents, (int)n_particles, + free(dest); + dest = tng_compress_vel_float((float *)*data, (int)n_particles, (int)n_frames, f_precision, 0, tng_data->compress_algo_vel, - &new_len); + &compressed_len); } } else { - dest = tng_compress_vel_find_algo((double *)temp_data_contents, (int)n_particles, - (int)algo_find_n_frames, - d_precision, - 0, tng_data-> - compress_algo_vel, - &new_len); + dest = tng_compress_vel((double *)*data, (int)n_particles, + (int)algo_find_n_frames, + d_precision, + 0, tng_data-> + compress_algo_vel, + &compressed_len); if(algo_find_n_frames < n_frames) { - dest = tng_compress_vel((double *)temp_data_contents, (int)n_particles, + free(dest); + dest = tng_compress_vel((double *)*data, (int)n_particles, (int)n_frames, d_precision, 0, tng_data->compress_algo_vel, - &new_len); + &compressed_len); } } } @@ -4998,77 +4539,52 @@ static tng_function_status tng_compress(tng_trajectory_t tng_data, { if(type == TNG_FLOAT_DATA) { - dest = tng_compress_vel_float((float *)temp_data_contents, (int)n_particles, + dest = tng_compress_vel_float((float *)*data, (int)n_particles, (int)n_frames, f_precision, 0, tng_data-> compress_algo_vel, - &new_len); + &compressed_len); } else { - dest = tng_compress_vel((double *)temp_data_contents, (int)n_particles, + dest = tng_compress_vel((double *)*data, (int)n_particles, (int)n_frames, d_precision, 0, tng_data-> compress_algo_vel, - &new_len); + &compressed_len); } } } else { fprintf(stderr, "TNG library: Can only compress positions and velocities using TNG-MF1 algorithms.\n"); - free(temp_data_contents); return(TNG_FAILURE); } - offset = (unsigned long)((char *)start_pos - block->block_contents); - if(alt_algo) { free(alt_algo); } - block->block_contents_size = new_len + offset; + free(*data); - free(temp_data_contents); + *data = (char *)dest; - temp = realloc(block->block_contents, block->block_contents_size); - if(!temp) - { - free(block->block_contents); - block->block_contents = 0; - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - block->block_contents_size, __FILE__, __LINE__); - return(TNG_CRITICAL); - } - block->block_contents = temp; - if(dest) - { - memcpy(temp + offset, dest, new_len); - free(dest); - } - else - { - fprintf(stderr, "TNG library: Error during TNG compression. %s: %d\n", __FILE__, __LINE__); - return(TNG_FAILURE); - } + *new_len = compressed_len; return(TNG_SUCCESS); } -static tng_function_status tng_uncompress(tng_trajectory_t tng_data, - tng_gen_block_t block, +static tng_function_status tng_uncompress(const tng_trajectory_t tng_data, + const tng_gen_block_t block, const char type, - void *start_pos, + char **data, const int64_t uncompressed_len) { - char *temp, *temp_data_contents; - int64_t compressed_len; double *d_dest = 0; float *f_dest = 0; - int64_t offset; int result; (void)tng_data; @@ -5087,17 +4603,6 @@ static tng_function_status tng_uncompress(tng_trajectory_t tng_data, return(TNG_FAILURE); } - compressed_len = block->block_contents_size - (int64_t)((char *)start_pos - (char *)block->block_contents); - temp_data_contents = malloc(compressed_len); - if(!temp_data_contents) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - uncompressed_len, __FILE__, __LINE__); - return(TNG_CRITICAL); - } - - memcpy(temp_data_contents, (char *)start_pos, compressed_len); - if(type == TNG_FLOAT_DATA) { f_dest = malloc(uncompressed_len); @@ -5105,10 +4610,13 @@ static tng_function_status tng_uncompress(tng_trajectory_t tng_data, { fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", uncompressed_len, __FILE__, __LINE__); - free(temp_data_contents); return(TNG_CRITICAL); } - result = tng_compress_uncompress_float(temp_data_contents, f_dest); + result = tng_compress_uncompress_float(*data, f_dest); + + free(*data); + + *data = (char *)f_dest; } else { @@ -5117,73 +4625,31 @@ static tng_function_status tng_uncompress(tng_trajectory_t tng_data, { fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", uncompressed_len, __FILE__, __LINE__); - free(temp_data_contents); return(TNG_CRITICAL); } - result = tng_compress_uncompress(temp_data_contents, d_dest); + result = tng_compress_uncompress(*data, d_dest); + + free(*data); + + *data = (char *)d_dest; } if(result == 1) { fprintf(stderr, "TNG library: Cannot uncompress TNG compressed block.\n"); - free(temp_data_contents); return(TNG_FAILURE); } - offset = (unsigned long)((char *)start_pos - (char *)block->block_contents); - - block->block_contents_size = (int64_t)(uncompressed_len + offset); - - temp = realloc(block->block_contents, uncompressed_len + offset); - if(!temp) - { - free(block->block_contents); - block->block_contents = 0; - if(d_dest) - { - free(d_dest); - } - if(f_dest) - { - free(f_dest); - } - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - block->block_contents_size, __FILE__, __LINE__); - free(temp_data_contents); - return(TNG_CRITICAL); - } - - if(type == TNG_FLOAT_DATA) - { - memcpy(temp + offset, f_dest, uncompressed_len); - } - else - { - memcpy(temp + offset, d_dest, uncompressed_len); - } - - block->block_contents = temp; - - free(temp_data_contents); - if(d_dest) - { - free(d_dest); - } - if(f_dest) - { - free(f_dest); - } return(TNG_SUCCESS); } #ifdef USE_ZLIB -static tng_function_status tng_gzip_compress(tng_trajectory_t tng_data, - tng_gen_block_t block, - void *start_pos, const int len) +static tng_function_status tng_gzip_compress(const tng_trajectory_t tng_data, + char **data, const int64_t len, + int64_t *new_len) { Bytef *dest; - char *temp; - unsigned long max_len, stat, offset; + uLongf stat, max_len; (void)tng_data; max_len = compressBound(len); @@ -5195,7 +4661,7 @@ static tng_function_status tng_gzip_compress(tng_trajectory_t tng_data, return(TNG_CRITICAL); } - stat = compress(dest, &max_len, start_pos, len); + stat = compress(dest, &max_len, (Bytef *)*data, len); if(stat != (unsigned long)Z_OK) { free(dest); @@ -5211,53 +4677,35 @@ static tng_function_status tng_gzip_compress(tng_trajectory_t tng_data, return(TNG_FAILURE); } - offset = (char *)start_pos - block->block_contents; - - block->block_contents_size = max_len + offset; - - temp = realloc(block->block_contents, block->block_contents_size); - if(!temp) - { - free(block->block_contents); - free(dest); - block->block_contents = 0; - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - block->block_contents_size, __FILE__, __LINE__); - return(TNG_CRITICAL); - } - - block->block_contents = temp; + *new_len = max_len; - memcpy(temp + offset, dest, max_len); + free(*data); - free(dest); + *data = (char *)dest; return(TNG_SUCCESS); } -static tng_function_status tng_gzip_uncompress(tng_trajectory_t tng_data, - tng_gen_block_t block, - void *start_pos, - unsigned long uncompressed_len) +static tng_function_status tng_gzip_uncompress(const tng_trajectory_t tng_data, + char **data, + const int64_t compressed_len, + const int64_t uncompressed_len) { Bytef *dest; - char *temp; unsigned long stat; - int offset; (void)tng_data; - - offset = (char *)start_pos - (char *)block->block_contents; + uLongf new_len = uncompressed_len; dest = malloc(uncompressed_len); if(!dest) { - fprintf(stderr, "TNG library: Cannot allocate memory (%lud bytes). %s: %d\n", + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", uncompressed_len, __FILE__, __LINE__); return(TNG_CRITICAL); } - stat = uncompress(dest, &uncompressed_len, (Bytef *) start_pos, - block->block_contents_size - offset); + stat = uncompress(dest, &new_len, (Bytef *) *data, + compressed_len); if(stat != Z_OK) { @@ -5279,30 +4727,16 @@ static tng_function_status tng_gzip_uncompress(tng_trajectory_t tng_data, return(TNG_FAILURE); } + free(*data); - block->block_contents_size = uncompressed_len + offset; - - temp = realloc(block->block_contents, uncompressed_len + offset); - if(!temp) - { - free(block->block_contents); - block->block_contents = 0; - free(dest); - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - block->block_contents_size, __FILE__, __LINE__); - return(TNG_CRITICAL); - } - - memcpy(temp + offset, dest, uncompressed_len); - - block->block_contents = temp; + *data = (char *)dest; - free(dest); return(TNG_SUCCESS); } #endif -/** Allocate memory for storing particle data. +/** + * @brief Allocate memory for storing particle data. * The allocated block will be refered to by data->values. * @param tng_data is a trajectory data container. * @param data is the data struct, which will contain the allocated memory in @@ -5315,10 +4749,10 @@ static tng_function_status tng_gzip_uncompress(tng_trajectory_t tng_data, * error has occured. */ static tng_function_status tng_allocate_particle_data_mem - (tng_trajectory_t tng_data, - tng_particle_data_t data, + (const tng_trajectory_t tng_data, + const tng_data_t data, int64_t n_frames, - int64_t stride_length, + const int64_t stride_length, const int64_t n_particles, const int64_t n_values_per_frame) { @@ -5422,9 +4856,9 @@ static tng_function_status tng_allocate_particle_data_mem } static tng_function_status tng_particle_data_find - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t id, - tng_particle_data_t *data) + tng_data_t *data) { int64_t block_index, i; tng_trajectory_frame_set_t frame_set = &tng_data-> @@ -5474,9 +4908,9 @@ static tng_function_status tng_particle_data_find } static tng_function_status tng_data_find - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t id, - tng_non_particle_data_t *data) + tng_data_t *data) { int64_t block_index, i; tng_trajectory_frame_set_t frame_set = &tng_data-> @@ -5539,14 +4973,13 @@ static tng_function_status tng_data_find static tng_function_status tng_data_block_len_calculate (const tng_trajectory_t tng_data, - const tng_particle_data_t data, + const tng_data_t data, const tng_bool is_particle_data, const int64_t n_frames, const int64_t frame_step, const int64_t stride_length, const int64_t num_first_particle, const int64_t n_particles, - const char dependency, int64_t *data_start_pos, int64_t *len) { @@ -5594,7 +5027,7 @@ static tng_function_status tng_data_block_len_calculate *len += sizeof(data->compression_multiplier); } - if(dependency & TNG_FRAME_DEPENDENT) + if(data->dependency & TNG_FRAME_DEPENDENT) { *len += sizeof(char); } @@ -5623,7 +5056,7 @@ static tng_function_status tng_data_block_len_calculate { for(i = 0; i < n_frames; i++) { - second_dim_values = ((tng_non_particle_data_t)data)->strings[i]; + second_dim_values = data->strings[0][i]; for(j = 0; j < data->n_values_per_frame; j++) { *len += strlen(second_dim_values[j]) + 1; @@ -5639,57 +5072,223 @@ static tng_function_status tng_data_block_len_calculate return(TNG_SUCCESS); } -/** Read the values of a particle data block +/* TEST: */ +/** + * @brief Create a non-particle data block + * @param tng_data is a trajectory data container. + * @param block_type_flag specifies if this is a trajectory block or a + * non-trajectory block. (TNG_TRAJECTORY_BLOCK or TNG_NON_TRAJECTORY_BLOCK) + * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major + * error has occured. + */ +static tng_function_status tng_data_block_create + (const tng_trajectory_t tng_data, + const char block_type_flag) +{ + tng_trajectory_frame_set_t frame_set = + &tng_data->current_trajectory_frame_set; + + tng_data_t data; + + if(block_type_flag == TNG_TRAJECTORY_BLOCK) + { + frame_set->n_data_blocks++; + data = realloc(frame_set->tr_data, sizeof(struct tng_data) * + frame_set->n_data_blocks); + if(!data) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n", + sizeof(struct tng_data) * frame_set->n_data_blocks, + __FILE__, __LINE__); + free(frame_set->tr_data); + frame_set->tr_data = 0; + return(TNG_CRITICAL); + } + frame_set->tr_data = data; + } + else + { + tng_data->n_data_blocks++; + data = realloc(tng_data->non_tr_data, sizeof(struct tng_data) * + tng_data->n_data_blocks); + if(!data) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n", + sizeof(struct tng_data) * tng_data->n_data_blocks, + __FILE__, __LINE__); + free(tng_data->non_tr_data); + tng_data->non_tr_data = 0; + return(TNG_CRITICAL); + } + tng_data->non_tr_data = data; + } + + return(TNG_SUCCESS); +} + +/* TEST: */ +/** + * @brief Allocate memory for storing non-particle data. + * The allocated block will be refered to by data->values. + * @param tng_data is a trajectory data container. + * @param data is the data struct, which will contain the allocated memory in + * data->values. + * @param n_frames is the number of frames of data to store. + * @param n_values_per_frame is the number of data values per frame. + * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major + * error has occured. + */ +static tng_function_status tng_allocate_data_mem + (const tng_trajectory_t tng_data, + const tng_data_t data, + int64_t n_frames, + const int64_t stride_length, + const int64_t n_values_per_frame) +{ + void **values; + int64_t i, j, size, frame_alloc; + (void)tng_data; + + if(n_values_per_frame == 0) + { + return(TNG_FAILURE); + } + + if(data->strings && data->datatype == TNG_CHAR_DATA) + { + for(i = 0; i < data->n_frames; i++) + { + for(j = 0; j < data->n_values_per_frame; j++) + { + if(data->strings[0][i][j]) + { + free(data->strings[0][i][j]); + data->strings[0][i][j] = 0; + } + } + free(data->strings[0][i]); + data->strings[0][i] = 0; + } + free(data->strings[0]); + data->strings[0] = 0; + free(data->strings); + } + data->n_frames = n_frames; + data->stride_length = tng_max_i64(1, stride_length); + n_frames = tng_max_i64(1, n_frames); + data->n_values_per_frame = n_values_per_frame; + frame_alloc = (n_frames % stride_length) ? n_frames / stride_length + 1 : n_frames / stride_length; + + if(data->datatype == TNG_CHAR_DATA) + { + data->strings = malloc(sizeof(char ***)); + data->strings[0] = malloc(sizeof(char **) * frame_alloc); + for(i = 0; i < frame_alloc; i++) + { + data->strings[0][i] = malloc(sizeof(char *) * n_values_per_frame); + if(!data->strings[0][i]) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", + n_values_per_frame, + __FILE__, __LINE__); + return(TNG_CRITICAL); + } + for(j = 0; j < n_values_per_frame; j++) + { + data->strings[0][i][j] = 0; + } + } + } + else + { + switch(data->datatype) + { + case TNG_INT_DATA: + size = sizeof(int64_t); + break; + case TNG_FLOAT_DATA: + size = sizeof(float); + break; + case TNG_DOUBLE_DATA: + default: + size = sizeof(double); + } + + values = realloc(data->values, + size * frame_alloc * + n_values_per_frame); + if(!values) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", + size * frame_alloc * + n_values_per_frame, + __FILE__, __LINE__); + free(data->values); + data->values = 0; + return(TNG_CRITICAL); + } + data->values = values; + } + + return(TNG_SUCCESS); +} + +/** + * @brief Read the values of a data block * @param tng_data is a trajectory data container. * @param block is the block to store the data (should already contain * the block headers and the block contents). - * @param offset is the reading offset to point at the place where the actual - * values are stored, starting from the beginning of the block_contents. The - * offset is changed during the reading. + * @param block_data_len is the length of the data contents of the block. * @param datatype is the type of data of the data block (char, int, float or * double). * @param num_first_particle is the number of the first particle in the data * block. This should be the same as in the corresponding particle mapping - * block. + * block. Only used if reading particle dependent data. * @param n_particles is the number of particles in the data block. This should - * be the same as in the corresponding particle mapping block. + * be the same as in the corresponding particle mapping block. Only used if + * reading particle dependent data. * @param first_frame_with_data is the frame number of the first frame with data * in this data block. * @param stride_length is the number of frames between each data entry. * @param n_frames is the number of frames in this data block. - * @param n_values is the number of values per particle and frame stored in this - * data block. + * @param n_values is the number of values per frame stored in this data block. * @param codec_id is the ID of the codec to compress the data. * @param multiplier is the multiplication factor applied to each data value * before compression. This factor is applied since some compression algorithms * work only on integers. + * @param hash_mode is an option to decide whether to generate/update the relevant md5 hashes. + * @param md5_state is a pointer to the current md5 storage, which will be updated appropriately + * if hash_mode == TNG_USE_HASH. * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major * error has occured. */ -static tng_function_status tng_particle_data_read - (tng_trajectory_t tng_data, - tng_gen_block_t block, - int *offset, - const char datatype, - const int64_t num_first_particle, - const int64_t n_particles, - const int64_t first_frame_with_data, - const int64_t stride_length, - int64_t n_frames, - const int64_t n_values, - const int64_t codec_id, - const double multiplier) +static tng_function_status tng_data_read(const tng_trajectory_t tng_data, + const tng_gen_block_t block, + const int64_t block_data_len, + const char datatype, + const int64_t num_first_particle, + const int64_t n_particles, + const int64_t first_frame_with_data, + const int64_t stride_length, + int64_t n_frames, + const int64_t n_values, + const int64_t codec_id, + const double multiplier, + const char hash_mode, + md5_state_t *md5_state) { - int64_t i, j, k, tot_n_particles, n_frames_div; + int64_t i, j, k, tot_n_particles, n_frames_div, offset; + int64_t full_data_len; int size, len; - int64_t data_size; char ***first_dim_values, **second_dim_values; - tng_particle_data_t data; + tng_data_t data; tng_trajectory_frame_set_t frame_set = &tng_data->current_trajectory_frame_set; - char block_type_flag; + char block_type_flag, *contents; + tng_bool is_particle_data; + tng_function_status stat; - TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer."); +/* fprintf(stderr, "TNG library: %s\n", block->name);*/ /* This must be caught early to avoid creating a data block if not necessary. */ #ifndef USE_ZLIB @@ -5717,42 +5316,90 @@ static tng_function_status tng_particle_data_read size = sizeof(double); } + if(n_particles > 0) + { + is_particle_data = TNG_TRUE; + } + else + { + if(codec_id == TNG_XTC_COMPRESSION || codec_id == TNG_TNG_COMPRESSION) + { + fprintf(stderr, "TNG library: Cannot uncompress data block. %s: %d\n", __FILE__, + __LINE__); + return(TNG_FAILURE); + } + is_particle_data = TNG_FALSE; + } + + if(is_particle_data == TNG_TRUE) + { + stat = tng_particle_data_find(tng_data, block->id, &data); + } + else + { + stat = tng_data_find(tng_data, block->id, &data); + } + + if(tng_data->current_trajectory_frame_set_input_file_pos > 0) + { + block_type_flag = TNG_TRAJECTORY_BLOCK; + } + else + { + block_type_flag = TNG_NON_TRAJECTORY_BLOCK; + } + /* If the block does not exist, create it */ - if(tng_particle_data_find(tng_data, block->id, &data) != TNG_SUCCESS) + if(stat != TNG_SUCCESS) { - if(tng_data->current_trajectory_frame_set_input_file_pos > 0) + if(is_particle_data == TNG_TRUE) { - block_type_flag = TNG_TRAJECTORY_BLOCK; + stat = tng_particle_data_block_create(tng_data, block_type_flag); } else { - block_type_flag = TNG_NON_TRAJECTORY_BLOCK; + stat = tng_data_block_create(tng_data, block_type_flag); } - if(tng_particle_data_block_create(tng_data, block_type_flag) != - TNG_SUCCESS) + if(stat != TNG_SUCCESS) { - fprintf(stderr, "TNG library: Cannot create particle data block. %s: %d\n", + fprintf(stderr, "TNG library: Cannot create data block. %s: %d\n", __FILE__, __LINE__); return(TNG_CRITICAL); } - if(block_type_flag == TNG_TRAJECTORY_BLOCK) + + if(is_particle_data == TNG_TRUE) { - data = &frame_set->tr_particle_data[frame_set-> - n_particle_data_blocks - 1]; + if(block_type_flag == TNG_TRAJECTORY_BLOCK) + { + data = &frame_set->tr_particle_data[frame_set-> + n_particle_data_blocks - 1]; + } + else + { + data = &tng_data->non_tr_particle_data[tng_data-> + n_particle_data_blocks - 1]; + } } else { - data = &tng_data->non_tr_particle_data[tng_data-> - n_particle_data_blocks - 1]; + if(block_type_flag == TNG_TRAJECTORY_BLOCK) + { + data = &frame_set->tr_data[frame_set->n_data_blocks - 1]; + } + else + { + data = &tng_data->non_tr_data[tng_data->n_data_blocks - 1]; + } } + data->block_id = block->id; data->block_name = malloc(strlen(block->name) + 1); if(!data->block_name) { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", - (int)strlen(block->name)+1, __FILE__, __LINE__); + fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", + (unsigned int)strlen(block->name)+1, __FILE__, __LINE__); return(TNG_CRITICAL); } strcpy(data->block_name, block->name); @@ -5763,27 +5410,70 @@ static tng_function_status tng_particle_data_read /* FIXME: Memory leak from strings. */ data->strings = 0; data->n_frames = 0; + data->dependency = 0; + if(is_particle_data == TNG_TRUE) + { + data->dependency += TNG_PARTICLE_DEPENDENT; + } + if(block_type_flag == TNG_TRAJECTORY_BLOCK && + (n_frames > 1 || + frame_set->n_frames == n_frames || + stride_length > 1)) + { + data->dependency += TNG_FRAME_DEPENDENT; + } data->codec_id = codec_id; data->compression_multiplier = multiplier; data->last_retrieved_frame = -1; } - if(/*block_type_flag == TNG_TRAJECTORY_BLOCK &&*/ - tng_data->current_trajectory_frame_set_input_file_pos > 0 && - tng_data->var_num_atoms_flag) + if(is_particle_data == TNG_TRUE) { - tot_n_particles = frame_set->n_particles; + if(block_type_flag == TNG_TRAJECTORY_BLOCK && + tng_data->var_num_atoms_flag) + { + tot_n_particles = frame_set->n_particles; + } + else + { + tot_n_particles = tng_data->n_particles; + } } + /* If there are no particles in this data block, still set tot_n_particles = 1 + * to calculate block lengths etc properly. */ else { - tot_n_particles = tng_data->n_particles; + tot_n_particles = 1; } n_frames_div = (n_frames % stride_length) ? n_frames / stride_length + 1 : n_frames / stride_length; + contents = malloc(block_data_len); + if(!contents) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", + block_data_len, __FILE__, __LINE__); + return(TNG_CRITICAL); + } + + if(fread(contents, block_data_len, 1, tng_data->input_file) == 0) + { + fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, __LINE__); + return(TNG_CRITICAL); + } + + if(hash_mode == TNG_USE_HASH) + { + md5_append(md5_state, (md5_byte_t *)contents, block_data_len); + } + if(codec_id != TNG_UNCOMPRESSED) { - data_size = (unsigned long)(n_frames_div * size * n_particles * n_values); + full_data_len = n_frames_div * size * n_values; + if(is_particle_data == TNG_TRUE) + { + full_data_len *= n_particles; + } switch(codec_id) { case TNG_XTC_COMPRESSION: @@ -5792,42 +5482,56 @@ static tng_function_status tng_particle_data_read case TNG_TNG_COMPRESSION: /* fprintf(stderr, "TNG library: Before TNG uncompression: %"PRId64"\n", block->block_contents_size);*/ if(tng_uncompress(tng_data, block, datatype, - block->block_contents + *offset, - data_size) != TNG_SUCCESS) + &contents, full_data_len) != TNG_SUCCESS) { fprintf(stderr, "TNG library: Could not read tng compressed block data. %s: %d\n", __FILE__, __LINE__); + free(contents); return(TNG_CRITICAL); } /* fprintf(stderr, "TNG library: After TNG uncompression: %"PRId64"\n", block->block_contents_size);*/ break; #ifdef USE_ZLIB case TNG_GZIP_COMPRESSION: -/* fprintf(stderr, "TNG library: Before GZIP uncompression: %"PRId64"\n", block->block_contents_size);*/ - if(tng_gzip_uncompress(tng_data, block, - block->block_contents + *offset, - data_size) != TNG_SUCCESS) + /* fprintf(stderr, "TNG library: Before compression: %"PRId64"\n", block->block_contents_size); */ + if(tng_gzip_uncompress(tng_data, &contents, + block_data_len, full_data_len) != TNG_SUCCESS) { fprintf(stderr, "TNG library: Could not read gzipped block data. %s: %d\n", __FILE__, __LINE__); + free(contents); return(TNG_CRITICAL); } -/* fprintf(stderr, "TNG library: After GZIP uncompression: %"PRId64"\n", block->block_contents_size);*/ + /* fprintf(stderr, "TNG library: After compression: %"PRId64"\n", block->block_contents_size); */ break; #endif } } + else + { + full_data_len = block_data_len; + } + /* Allocate memory */ if(!data->values || data->n_frames != n_frames || data->n_values_per_frame != n_values) { - if(tng_allocate_particle_data_mem(tng_data, data, n_frames, - stride_length, - tot_n_particles, n_values) != - TNG_SUCCESS) + if(is_particle_data == TNG_TRUE) { - fprintf(stderr, "TNG library: Cannot allocate memory for particle data. %s: %d\n", + stat = tng_allocate_particle_data_mem(tng_data, data, n_frames, + stride_length, + tot_n_particles, n_values); + } + else + { + stat = tng_allocate_data_mem(tng_data, data, n_frames, stride_length, + n_values); + } + if(stat != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot allocate memory for data. %s: %d\n", __FILE__, __LINE__); + free(contents); return(TNG_CRITICAL); } } @@ -5836,47 +5540,83 @@ static tng_function_status tng_particle_data_read if(datatype == TNG_CHAR_DATA) { - for(i = 0; i < n_frames_div; i++) + offset = 0; + /* Strings are stores slightly differently if the data block contains particle + * data (frames * particles * n_values) or not (frames * n_values). */ + if(is_particle_data == TNG_TRUE) { - first_dim_values = data->strings[i]; - for(j = num_first_particle; j < num_first_particle + n_particles; - j++) + for(i = 0; i < n_frames_div; i++) { - second_dim_values = first_dim_values[j]; - for(k = 0; k < n_values; k++) + first_dim_values = data->strings[i]; + for(j = num_first_particle; j < num_first_particle + n_particles; + j++) { - len = tng_min_i((int)strlen(block->block_contents+*offset) + 1, - TNG_MAX_STR_LEN); - if(second_dim_values[k]) + second_dim_values = first_dim_values[j]; + for(k = 0; k < n_values; k++) + { + len = tng_min_size(strlen(contents+offset) + 1, + TNG_MAX_STR_LEN); + if(second_dim_values[k]) + { + free(second_dim_values[k]); + } + second_dim_values[k] = malloc(len); + if(!second_dim_values[k]) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", + len, __FILE__, __LINE__); + free(contents); + return(TNG_CRITICAL); + } + strncpy(second_dim_values[k], contents+offset, len); + offset += len; + } + } + } + } + else + { + for(i = 0; i < n_frames_div; i++) + { + for(j = 0; j < n_values; j++) + { + len = tng_min_size(strlen(contents+offset) + 1, + TNG_MAX_STR_LEN); + if(data->strings[0][i][j]) { - free(second_dim_values[k]); + free(data->strings[0][i][j]); } - second_dim_values[k] = malloc(len); - if(!second_dim_values[k]) + data->strings[0][i][j] = malloc(len); + if(!data->strings[0][i][j]) { fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", - len, __FILE__, __LINE__); + len, __FILE__, __LINE__); + free(contents); return(TNG_CRITICAL); } - strncpy(second_dim_values[k], - block->block_contents+*offset, len); - *offset += len; + strncpy(data->strings[0][i][j], contents+offset, len); + offset += len; } } } } else { - memcpy((char *)data->values + n_frames_div * size * n_values * - num_first_particle, - block->block_contents + *offset, - block->block_contents_size - *offset); + if(is_particle_data) + { + memcpy((char *)data->values + n_frames_div * size * n_values * + num_first_particle, contents, full_data_len); + } + else + { + memcpy(data->values, contents, full_data_len); + } switch(datatype) { case TNG_FLOAT_DATA: if(tng_data->input_endianness_swap_func_32) { - for(i = 0; i < (block->block_contents_size - *offset); i+=size) + for(i = 0; i < full_data_len; i+=size) { if(tng_data->input_endianness_swap_func_32(tng_data, (int32_t *)((char *)data->values + i)) @@ -5892,7 +5632,7 @@ static tng_function_status tng_particle_data_read case TNG_DOUBLE_DATA: if(tng_data->input_endianness_swap_func_64) { - for(i = 0; i < (block->block_contents_size - *offset); i+=size) + for(i = 0; i < full_data_len; i+=size) { if(tng_data->input_endianness_swap_func_64(tng_data, (int64_t *)((char *)data->values + i)) @@ -5908,42 +5648,47 @@ static tng_function_status tng_particle_data_read break; } } + + free(contents); + return(TNG_SUCCESS); } -/** Write a particle data block +/** + * @brief Write 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 and the block contents). * @param block_index is the index number of the data block in the frame set. + * @param is_particle_data is a flag to specify if the data to write is + * particle dependent or not. * @param mapping is the particle mapping that is relevant for the data block. + * Only relevant if writing particle dependent data. * @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 will be generated and written. * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major * error has occured. */ -static tng_function_status tng_particle_data_block_write - (tng_trajectory_t tng_data, - tng_gen_block_t block, - const int64_t block_index, - const tng_particle_mapping_t mapping, - const char hash_mode) +static tng_function_status tng_data_block_write(const tng_trajectory_t tng_data, + const tng_gen_block_t block, + const int64_t block_index, + const tng_bool is_particle_data, + const tng_particle_mapping_t mapping, + const char hash_mode) { int64_t n_particles, num_first_particle, n_frames, stride_length; - int64_t frame_step, data_start_pos; - int64_t i, j, k; + int64_t full_data_len, block_data_len, frame_step, data_start_pos; + int64_t i, j, k, curr_file_pos, header_file_pos; int size; - size_t len, offset = 0; - char dependency, temp, *temp_name; - double multiplier; - char ***first_dim_values, **second_dim_values; - tng_trajectory_frame_set_t frame_set; + size_t len; tng_function_status stat; - - tng_particle_data_t data; + char temp, *temp_name, ***first_dim_values, **second_dim_values, *contents; + double multiplier; + tng_trajectory_frame_set_t frame_set = + &tng_data->current_trajectory_frame_set; + tng_data_t data; char block_type_flag; - - frame_set = &tng_data->current_trajectory_frame_set; + md5_state_t md5_state; /* If we have already started writing frame sets it is too late to write * non-trajectory data blocks */ @@ -5961,23 +5706,47 @@ static tng_function_status tng_particle_data_block_write return(TNG_CRITICAL); } - if(block_type_flag == TNG_TRAJECTORY_BLOCK) + if(is_particle_data == TNG_TRUE) { - data = &frame_set->tr_particle_data[block_index]; + if(block_type_flag == TNG_TRAJECTORY_BLOCK) + { + data = &frame_set->tr_particle_data[block_index]; + + /* If this data block has not had any data added in this frame set + * do not write it. */ + if(data->first_frame_with_data < frame_set->first_frame) + { + return(TNG_SUCCESS); + } - /* If this data block has not had any data added in this frame set - * do not write it. */ - if(data->first_frame_with_data < frame_set->first_frame) + stride_length = tng_max_i64(1, data->stride_length); + } + else { - return(TNG_SUCCESS); + data = &tng_data->non_tr_particle_data[block_index]; + stride_length = 1; } - - stride_length = tng_max_i64(1, data->stride_length); } else { - data = &tng_data->non_tr_particle_data[block_index]; - stride_length = 1; + if(block_type_flag == TNG_TRAJECTORY_BLOCK) + { + data = &frame_set->tr_data[block_index]; + + /* If this data block has not had any data added in this frame set + * do not write it. */ + if(data->first_frame_with_data < frame_set->first_frame) + { + return(TNG_SUCCESS); + } + + stride_length = tng_max_i64(1, data->stride_length); + } + else + { + data = &tng_data->non_tr_data[block_index]; + stride_length = 1; + } } switch(data->datatype) @@ -6003,7 +5772,7 @@ static tng_function_status tng_particle_data_block_write temp_name = realloc(block->name, len); if(!temp_name) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n", len, + fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n", len+1, __FILE__, __LINE__); free(block->name); block->name = 0; @@ -6045,63 +5814,81 @@ static tng_function_status tng_particle_data_block_write data->compression_multiplier = 1.0; } - if(mapping && mapping->n_particles != 0) - { - n_particles = mapping->n_particles; - num_first_particle = mapping->num_first_particle; - } - else + if(data->dependency & TNG_PARTICLE_DEPENDENT) { - num_first_particle = 0; - if(tng_data->var_num_atoms_flag) + if(mapping && mapping->n_particles != 0) { - n_particles = frame_set->n_particles; + n_particles = mapping->n_particles; + num_first_particle = mapping->num_first_particle; } else { - n_particles = tng_data->n_particles; + num_first_particle = 0; + if(tng_data->var_num_atoms_flag) + { + n_particles = frame_set->n_particles; + } + else + { + n_particles = tng_data->n_particles; + } } } - if(block_type_flag == TNG_TRAJECTORY_BLOCK && data->n_frames > 0) + if(data->dependency & TNG_PARTICLE_DEPENDENT) { - dependency = TNG_FRAME_DEPENDENT + TNG_PARTICLE_DEPENDENT; + if(tng_data_block_len_calculate(tng_data, data, TNG_TRUE, n_frames, + frame_step, stride_length, num_first_particle, + n_particles, &data_start_pos, + &block->block_contents_size) != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot calculate length of particle data block. %s: %d\n", + __FILE__, __LINE__); + return(TNG_CRITICAL); + } } else { - dependency = TNG_PARTICLE_DEPENDENT; + if(tng_data_block_len_calculate(tng_data, data, TNG_FALSE, n_frames, + frame_step, stride_length, 0, + 1, &data_start_pos, + &block->block_contents_size) != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot calculate length of non-particle data block. %s: %d\n", + __FILE__, __LINE__); + return(TNG_CRITICAL); + } } - if(tng_data_block_len_calculate(tng_data, data, TNG_TRUE, n_frames, - frame_step, stride_length, num_first_particle, - n_particles, dependency, &data_start_pos, - &block->block_contents_size) != TNG_SUCCESS) + header_file_pos = ftello(tng_data->output_file); + + if(tng_block_header_write(tng_data, block) != TNG_SUCCESS) { - fprintf(stderr, "TNG library: Cannot calculate length of particle data block. %s: %d\n", - __FILE__, __LINE__); + fprintf(stderr, "TNG library: Cannot write header of file %s. %s: %d\n", + tng_data->output_file_path, __FILE__, __LINE__); return(TNG_CRITICAL); } - if(block->block_contents) + if(hash_mode == TNG_USE_HASH) { - free(block->block_contents); + md5_init(&md5_state); } - block->block_contents = malloc(block->block_contents_size); - if(!block->block_contents) + + if(tng_file_output_numerical(tng_data, &data->datatype, + sizeof(data->datatype), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - block->block_contents_size, __FILE__, __LINE__); return(TNG_CRITICAL); } + if(tng_file_output_numerical(tng_data, &data->dependency, + sizeof(data->dependency), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } - memcpy(block->block_contents, &data->datatype, sizeof(char)); - offset += sizeof(char); - - memcpy(block->block_contents+offset, &dependency, sizeof(char)); - offset += sizeof(char); - - if(dependency & TNG_FRAME_DEPENDENT) + if(data->dependency & TNG_FRAME_DEPENDENT) { if(stride_length > 1) { @@ -6111,53 +5898,36 @@ static tng_function_status tng_particle_data_block_write { temp = 0; } - memcpy(block->block_contents+offset, &temp, sizeof(char)); - offset += sizeof(char); + if(tng_file_output_numerical(tng_data, &temp, + sizeof(temp), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } } - memcpy(block->block_contents+offset, &data->n_values_per_frame, - sizeof(data->n_values_per_frame)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &data->n_values_per_frame, + sizeof(data->n_values_per_frame), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(data->n_values_per_frame); - memcpy(block->block_contents+offset, &data->codec_id, - sizeof(data->codec_id)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &data->codec_id, + sizeof(data->codec_id), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(data->codec_id); if(data->codec_id != TNG_UNCOMPRESSED) { - memcpy(block->block_contents+offset, &data->compression_multiplier, - sizeof(data->compression_multiplier)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &data->compression_multiplier, + sizeof(data->compression_multiplier), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(data->compression_multiplier); } if(data->n_frames > 0 && stride_length > 1) @@ -6167,156 +5937,147 @@ static tng_function_status tng_particle_data_block_write { data->first_frame_with_data = frame_set->first_frame; } - memcpy(block->block_contents+offset, &data->first_frame_with_data, - sizeof(data->first_frame_with_data)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &data->first_frame_with_data, + sizeof(data->first_frame_with_data), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(data->first_frame_with_data); - memcpy(block->block_contents+offset, &stride_length, - sizeof(stride_length)); - if(tng_data->output_endianness_swap_func_64) + if(tng_file_output_numerical(tng_data, &stride_length, + sizeof(stride_length), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_CRITICAL); } - offset += sizeof(stride_length); } - - memcpy(block->block_contents+offset, &num_first_particle, - sizeof(num_first_particle)); - if(tng_data->output_endianness_swap_func_64) + if(data->dependency & TNG_PARTICLE_DEPENDENT) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) + if(tng_file_output_numerical(tng_data, &num_first_particle, + sizeof(num_first_particle), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); + return(TNG_CRITICAL); } - } - offset += sizeof(num_first_particle); - memcpy(block->block_contents+offset, &n_particles, sizeof(n_particles)); - if(tng_data->output_endianness_swap_func_64) - { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) + if(tng_file_output_numerical(tng_data, &n_particles, + sizeof(n_particles), + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); + return(TNG_CRITICAL); } } - offset += sizeof(n_particles); if(data->datatype == TNG_CHAR_DATA) { if(data->strings) { - for(i = 0; i < frame_step; i++) + if(data->dependency & TNG_PARTICLE_DEPENDENT) { - first_dim_values = data->strings[i]; - for(j = num_first_particle; j < num_first_particle + n_particles; - j++) + for(i = 0; i < frame_step; i++) { - second_dim_values = first_dim_values[j]; - for(k = 0; k < data->n_values_per_frame; k++) + first_dim_values = data->strings[i]; + for(j = num_first_particle; j < num_first_particle + n_particles; + j++) { - len = (unsigned int)strlen(second_dim_values[k]) + 1; - strncpy(block->block_contents+offset, - second_dim_values[k], len); - offset += len; + second_dim_values = first_dim_values[j]; + for(k = 0; k < data->n_values_per_frame; k++) + { + if(tng_fwritestr(tng_data, second_dim_values[k], + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } + } } } } - } - } - else if(data->values) - { - memcpy(block->block_contents + offset, data->values, - block->block_contents_size - offset); - - switch(data->datatype) - { - case TNG_FLOAT_DATA: - if(data->codec_id == TNG_UNCOMPRESSED || data-> codec_id == TNG_GZIP_COMPRESSION || - data->codec_id == TNG_TNG_COMPRESSION) + else { - if(tng_data->input_endianness_swap_func_32) + for(i = 0; i < frame_step; i++) { - for(i = offset; i < block->block_contents_size; i+=size) + for(j = 0; j < data->n_values_per_frame; j++) { - if(tng_data->input_endianness_swap_func_32(tng_data, - (int32_t *)(block->block_contents + i)) - != TNG_SUCCESS) + if(tng_fwritestr(tng_data, data->strings[0][i][j], + hash_mode, &md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); + return(TNG_CRITICAL); } } } } - else + } + } + else + { + if(data->dependency & TNG_PARTICLE_DEPENDENT) + { + full_data_len = size * frame_step * n_particles * data->n_values_per_frame; + } + else + { + full_data_len = size * frame_step * data->n_values_per_frame; + } + contents = malloc(full_data_len); + if(!contents) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", + full_data_len, __FILE__, __LINE__); + return(TNG_CRITICAL); + } + + if(data->values) + { + memcpy(contents, data->values, full_data_len); + switch(data->datatype) { - multiplier = data->compression_multiplier; - if(fabs(multiplier - 1.0) > 0.00001 || - tng_data->input_endianness_swap_func_32) + case TNG_FLOAT_DATA: + if(data->codec_id == TNG_UNCOMPRESSED || data-> codec_id == TNG_GZIP_COMPRESSION || + data->codec_id == TNG_TNG_COMPRESSION) { - for(i = offset; i < block->block_contents_size; i+=size) + if(tng_data->output_endianness_swap_func_32) { - *(float *)(block->block_contents + i) *= (float)multiplier; - if(tng_data->input_endianness_swap_func_32 && - tng_data->input_endianness_swap_func_32(tng_data, - (int32_t *)(block->block_contents + i)) - != TNG_SUCCESS) + for(i = 0; i < full_data_len; i+=size) { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); + if(tng_data->output_endianness_swap_func_32(tng_data, + (int32_t *)(contents + i)) + != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); + } } } } - } - break; - case TNG_INT_DATA: - if(tng_data->input_endianness_swap_func_64) - { - for(i = offset; i < block->block_contents_size; i+=size) + else { - if(tng_data->input_endianness_swap_func_64(tng_data, - (int64_t *)(block->block_contents + i)) - != TNG_SUCCESS) + multiplier = data->compression_multiplier; + if(fabs(multiplier - 1.0) > 0.00001 || + tng_data->output_endianness_swap_func_32) { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); + for(i = 0; full_data_len; i+=size) + { + *(float *)(contents + i) *= (float)multiplier; + if(tng_data->output_endianness_swap_func_32 && + tng_data->output_endianness_swap_func_32(tng_data, + (int32_t *)(contents + i)) + != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); + } + } } } - } - break; - case TNG_DOUBLE_DATA: - if(data->codec_id == TNG_UNCOMPRESSED || data-> codec_id == TNG_GZIP_COMPRESSION || - data->codec_id == TNG_TNG_COMPRESSION) - { - if(tng_data->input_endianness_swap_func_64) + break; + case TNG_INT_DATA: + if(tng_data->output_endianness_swap_func_64) { - for(i = offset; i < block->block_contents_size; i+=size) + for(i = 0; i < full_data_len; i+=size) { - if(tng_data->input_endianness_swap_func_64(tng_data, - (int64_t *)(block->block_contents + i)) + if(tng_data->output_endianness_swap_func_64(tng_data, + (int64_t *)(contents + i)) != TNG_SUCCESS) { fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", @@ -6324,42 +6085,57 @@ static tng_function_status tng_particle_data_block_write } } } - } - else - { - multiplier = data->compression_multiplier; - if(fabs(multiplier - 1.0) > 0.00001 || - tng_data->input_endianness_swap_func_64) + break; + case TNG_DOUBLE_DATA: + if(data->codec_id == TNG_UNCOMPRESSED || data-> codec_id == TNG_GZIP_COMPRESSION || + data->codec_id == TNG_TNG_COMPRESSION) { - for(i = offset; i < block->block_contents_size; i+=size) + if(tng_data->output_endianness_swap_func_64) { - *(double *)(block->block_contents + i) *= multiplier; - if(tng_data->input_endianness_swap_func_64 && - tng_data->input_endianness_swap_func_64(tng_data, - (int64_t *)(block->block_contents + i)) - != TNG_SUCCESS) + for(i = 0; i < full_data_len; i+=size) { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); + if(tng_data->output_endianness_swap_func_64(tng_data, + (int64_t *)(contents + i)) + != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); + } } } } + else + { + multiplier = data->compression_multiplier; + if(fabs(multiplier - 1.0) > 0.00001 || + tng_data->output_endianness_swap_func_64) + { + for(i = 0; i < full_data_len; i+=size) + { + *(double *)(contents + i) *= multiplier; + if(tng_data->output_endianness_swap_func_64 && + tng_data->output_endianness_swap_func_64(tng_data, + (int64_t *)(contents + i)) + != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); + } + } + } + } + break; + case TNG_CHAR_DATA: + break; } - break; - case TNG_CHAR_DATA: - break; } - } - else - { - memset(block->block_contents+offset, 0, block->block_contents_size - offset); - } + else + { + memset(contents, 0, full_data_len); + } - frame_set->n_written_frames += frame_set->n_unwritten_frames; - frame_set->n_unwritten_frames = 0; + block_data_len = full_data_len; - if(block_type_flag == TNG_NON_TRAJECTORY_BLOCK || frame_set->n_written_frames > 0) - { switch(data->codec_id) { case TNG_XTC_COMPRESSION: @@ -6369,7 +6145,7 @@ static tng_function_status tng_particle_data_block_write case TNG_TNG_COMPRESSION: stat = tng_compress(tng_data, block, frame_step, n_particles, data->datatype, - block->block_contents + data_start_pos); + &contents, &block_data_len); if(stat != TNG_SUCCESS) { fprintf(stderr, "TNG library: Could not write tng compressed block data. %s: %d\n", @@ -6381,18 +6157,20 @@ static tng_function_status tng_particle_data_block_write /* Set the data again, but with no compression (to write only * the relevant data) */ data->codec_id = TNG_UNCOMPRESSED; - stat = tng_particle_data_block_write(tng_data, block, - block_index, mapping, - hash_mode); + stat = tng_data_block_write(tng_data, block, + block_index, is_particle_data, mapping, + hash_mode); + free(contents); return(stat); } break; #ifdef USE_ZLIB case TNG_GZIP_COMPRESSION: - /* fprintf(stderr, "TNG library: Before compression: %"PRId64"\n", block->block_contents_size);*/ - stat = tng_gzip_compress(tng_data, block, - block->block_contents + data_start_pos, - block->block_contents_size - data_start_pos); + /* fprintf(stderr, "TNG library: Before compression: %"PRId64"\n", block->block_contents_size); */ + stat = tng_gzip_compress(tng_data, + &contents, + full_data_len, + &block_data_len); if(stat != TNG_SUCCESS) { fprintf(stderr, "TNG library: Could not write gzipped block data. %s: %d\n", __FILE__, @@ -6401,1768 +6179,1475 @@ static tng_function_status tng_particle_data_block_write { return(TNG_CRITICAL); } - /* Set the data again, but with no compression (to write only - * the relevant data) */ data->codec_id = TNG_UNCOMPRESSED; - stat = tng_particle_data_block_write(tng_data, block, - block_index, mapping, - hash_mode); - return(stat); } - /* fprintf(stderr, "TNG library: After compression: %"PRId64"\n", block->block_contents_size);*/ + /* fprintf(stderr, "TNG library: After compression: %"PRId64"\n", block->block_contents_size); */ break; #endif } - } + if(block_data_len != full_data_len) + { + block->block_contents_size -= full_data_len - block_data_len; - if(tng_block_header_write(tng_data, block, hash_mode) != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot write header of file %s. %s: %d\n", - tng_data->output_file_path, __FILE__, __LINE__); - return(TNG_CRITICAL); + curr_file_pos = ftello(tng_data->output_file); + fseeko(tng_data->output_file, header_file_pos + sizeof(block->header_contents_size), SEEK_SET); + + if(tng_file_output_numerical(tng_data, &block->block_contents_size, + sizeof(block->block_contents_size), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } + fseeko(tng_data->output_file, curr_file_pos, SEEK_SET); + } + if(fwrite(contents, block_data_len, 1, tng_data->output_file) != 1) + { + fprintf(stderr, "TNG library: Could not write all block data. %s: %d\n", __FILE__, + __LINE__); + return(TNG_CRITICAL); + } + if(hash_mode == TNG_USE_HASH) + { + md5_append(&md5_state, (md5_byte_t *)contents, block_data_len); + } + + free(contents); } - if(fwrite(block->block_contents, block->block_contents_size, 1, - tng_data->output_file) != 1) + if(hash_mode == TNG_USE_HASH) { - fprintf(stderr, "TNG library: Could not write all block data. %s: %d\n", __FILE__, - __LINE__); - return(TNG_CRITICAL); + md5_finish(&md5_state, (md5_byte_t *)block->md5_hash); + curr_file_pos = ftello(tng_data->output_file); + fseeko(tng_data->output_file, header_file_pos + + 3 * sizeof(int64_t), SEEK_SET); + if(fwrite(block->md5_hash, TNG_MD5_HASH_LEN, 1, tng_data->output_file) != 1) + { + fprintf(stderr, "TNG library: Could not write MD5 hash. %s: %d\n", __FILE__, + __LINE__); + return(TNG_CRITICAL); + } + fseeko(tng_data->output_file, curr_file_pos, SEEK_SET); } + frame_set->n_written_frames += frame_set->n_unwritten_frames; + frame_set->n_unwritten_frames = 0; + return(TNG_SUCCESS); } -/* TEST: */ -/** Create a non-particle data block +/** + * @brief Read the meta information of a data block (particle or non-particle data). * @param tng_data is a trajectory data container. - * @param block_type_flag specifies if this is a trajectory block or a - * non-trajectory block. (TNG_TRAJECTORY_BLOCK or TNG_NON_TRAJECTORY_BLOCK) + * @param datatype is set to the datatype of the data block. + * @param dependency is set to the dependency (particle and/or frame dependent) + * @param sparse_data is set to TRUE if data is not written every frame. + * @param n_values is set to the number of values per frame of the data. + * @param codec_id is set to the ID of the codec used to compress the data. + * @param first_frame_with_data is set to the first frame with data (only relevant if + * sparse_data == TRUE). + * @param stride_length is set to the writing interval of the data (1 if sparse_data + * == FALSE). + * @param num_first_particle is set to the number of the first particle with data written + * in this block. + * @param block_n_particles is set to the number of particles in this data block. + * @param multiplier is set to the compression multiplier. + * @param hash_mode specifies whether to check if the hash matches the contents or not. + * @param md5_state is the md5 hash of the block (only used if hash_mode == TNG_USE_HASH). * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major * error has occured. */ -static tng_function_status tng_data_block_create - (tng_trajectory_t tng_data, - const char block_type_flag) +static tng_function_status tng_data_block_meta_information_read + (const tng_trajectory_t tng_data, + 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, + const char hash_mode, + md5_state_t *md5_state) { - tng_trajectory_frame_set_t frame_set = - &tng_data->current_trajectory_frame_set; - - tng_non_particle_data_t data; + if(tng_file_input_numerical(tng_data, datatype, + sizeof(*datatype), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } - if(block_type_flag == TNG_TRAJECTORY_BLOCK) + if(tng_file_input_numerical(tng_data, dependency, + sizeof(*dependency), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - frame_set->n_data_blocks++; - data = realloc(frame_set->tr_data, sizeof(struct tng_non_particle_data) * - frame_set->n_data_blocks); - if(!data) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n", - sizeof(struct tng_non_particle_data) * frame_set->n_data_blocks, - __FILE__, __LINE__); - free(frame_set->tr_data); - frame_set->tr_data = 0; - return(TNG_CRITICAL); - } - frame_set->tr_data = data; + return(TNG_CRITICAL); } - else + + if(*dependency & TNG_FRAME_DEPENDENT) { - tng_data->n_data_blocks++; - data = realloc(tng_data->non_tr_data, sizeof(struct tng_non_particle_data) * - tng_data->n_data_blocks); - if(!data) + if(tng_file_input_numerical(tng_data, sparse_data, + sizeof(*sparse_data), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n", - sizeof(struct tng_non_particle_data) * tng_data->n_data_blocks, - __FILE__, __LINE__); - free(tng_data->non_tr_data); - tng_data->non_tr_data = 0; return(TNG_CRITICAL); } - tng_data->non_tr_data = data; } - return(TNG_SUCCESS); -} - -/* TEST: */ -/** Allocate memory for storing non-particle data. - * The allocated block will be refered to by data->values. - * @param tng_data is a trajectory data container. - * @param data is the data struct, which will contain the allocated memory in - * data->values. - * @param n_frames is the number of frames of data to store. - * @param n_values_per_frame is the number of data values per frame. - * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major - * error has occured. - */ -static tng_function_status tng_allocate_data_mem - (tng_trajectory_t tng_data, - tng_non_particle_data_t data, - int64_t n_frames, - int64_t stride_length, - const int64_t n_values_per_frame) -{ - void **values; - int64_t i, j, size, frame_alloc; - (void)tng_data; + if(tng_file_input_numerical(tng_data, n_values, + sizeof(*n_values), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } - if(n_values_per_frame == 0) + if(tng_file_input_numerical(tng_data, codec_id, + sizeof(*codec_id), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - return(TNG_FAILURE); + return(TNG_CRITICAL); } - if(data->strings && data->datatype == TNG_CHAR_DATA) + if(*codec_id != TNG_UNCOMPRESSED) { - for(i = 0; i < data->n_frames; i++) + if(tng_file_input_numerical(tng_data, multiplier, + sizeof(*multiplier), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - for(j = 0; j < data->n_values_per_frame; j++) - { - if(data->strings[i][j]) - { - free(data->strings[i][j]); - data->strings[i][j] = 0; - } - } - free(data->strings[i]); - data->strings[i] = 0; + return(TNG_CRITICAL); } - free(data->strings); } - data->n_frames = n_frames; - data->stride_length = tng_max_i64(1, stride_length); - n_frames = tng_max_i64(1, n_frames); - data->n_values_per_frame = n_values_per_frame; - frame_alloc = (n_frames % stride_length) ? n_frames / stride_length + 1 : n_frames / stride_length; + else + { + *multiplier = 1; + } - if(data->datatype == TNG_CHAR_DATA) + if(*dependency & TNG_FRAME_DEPENDENT) { - data->strings = malloc(sizeof(char **) * frame_alloc); - for(i = 0; i < frame_alloc; i++) + if(*sparse_data) { - data->strings[i] = malloc(sizeof(char *) * n_values_per_frame); - if(!data->strings[i]) + if(tng_file_input_numerical(tng_data, first_frame_with_data, + sizeof(*first_frame_with_data), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - n_values_per_frame, - __FILE__, __LINE__); return(TNG_CRITICAL); } - for(j = 0; j < n_values_per_frame; j++) + + if(tng_file_input_numerical(tng_data, stride_length, + sizeof(*stride_length), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - data->strings[i][j] = 0; + return(TNG_CRITICAL); } + + *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 = tng_data->current_trajectory_frame_set.first_frame; + *stride_length = 1; + *n_frames = tng_data->current_trajectory_frame_set.n_frames; } } else { - switch(data->datatype) + *first_frame_with_data = 0; + *stride_length = 1; + *n_frames = 1; + } + + if (*dependency & TNG_PARTICLE_DEPENDENT) + { + if(tng_file_input_numerical(tng_data, num_first_particle, + sizeof(*num_first_particle), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - case TNG_INT_DATA: - size = sizeof(int64_t); - break; - case TNG_FLOAT_DATA: - size = sizeof(float); - break; - case TNG_DOUBLE_DATA: - default: - size = sizeof(double); + return(TNG_CRITICAL); } - values = realloc(data->values, - size * frame_alloc * - n_values_per_frame); - if(!values) + if(tng_file_input_numerical(tng_data, block_n_particles, + sizeof(*block_n_particles), + hash_mode, md5_state, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - size * frame_alloc * - n_values_per_frame, - __FILE__, __LINE__); - free(data->values); - data->values = 0; return(TNG_CRITICAL); } - data->values = values; + } + else + { + *num_first_particle = -1; + *block_n_particles = 0; } return(TNG_SUCCESS); } -/** Read the values of a non-particle data block +/** + * @brief 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 and the block contents). - * @param offset is the reading offset to point at the place where the actual - * values are stored, starting from the beginning of the block_contents. The - * offset is changed during the reading. - * @param datatype is the type of data of the data block (char, int, float or - * double). - * @param first_frame_with_data is the frame number of the first frame with data - * in this data block. - * @param stride_length is the number of frames between each data entry. - * @param n_frames is the number of frames in this data block. - * @param n_values is the number of values per frame stored in this data block. - * @param codec_id is the ID of the codec to compress the data. - * @param multiplier is the multiplication factor applied to each data value - * before compression. This factor is applied since some compression algorithms - * work only on integers. + * 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_read(tng_trajectory_t tng_data, - tng_gen_block_t block, - int *offset, - const char datatype, - const int64_t first_frame_with_data, - const int64_t stride_length, - int64_t n_frames, - const int64_t n_values, - const int64_t codec_id, - const double multiplier) +static tng_function_status tng_data_block_contents_read + (const tng_trajectory_t tng_data, + const tng_gen_block_t block, + const char hash_mode) { - int64_t i, j, n_frames_div; - int size, len; -#ifdef USE_ZLIB - int64_t data_size; -#endif - tng_non_particle_data_t data; - tng_trajectory_frame_set_t frame_set = - &tng_data->current_trajectory_frame_set; - char block_type_flag; - - TNG_ASSERT(offset != 0, "TNG library: offset must not be a NULL pointer."); - -/* fprintf(stderr, "TNG library: %s\n", block->name);*/ + int64_t start_pos, n_values, codec_id, n_frames, first_frame_with_data; + int64_t remaining_len, stride_length, block_n_particles, num_first_particle; + double multiplier; + char datatype, dependency, sparse_data; + tng_function_status stat = TNG_SUCCESS; + char hash[TNG_MD5_HASH_LEN]; + md5_state_t md5_state; - /* This must be caught early to avoid creating a data block if not necessary. */ -#ifndef USE_ZLIB - if(codec_id == TNG_GZIP_COMPRESSION) + if(tng_input_file_init(tng_data) != TNG_SUCCESS) { - fprintf(stderr, "TNG library: Cannot uncompress data block. %s: %d\n", __FILE__, - __LINE__); - return(TNG_FAILURE); + return(TNG_CRITICAL); } -#endif - switch(datatype) + start_pos = ftello(tng_data->input_file); + + if(hash_mode == TNG_USE_HASH) { - case TNG_CHAR_DATA: - size = 1; - break; - case TNG_INT_DATA: - size = sizeof(int64_t); - break; - case TNG_FLOAT_DATA: - size = sizeof(float); - break; - case TNG_DOUBLE_DATA: - default: - size = sizeof(double); + md5_init(&md5_state); } - /* If the block does not exist, create it */ - if(tng_data_find(tng_data, block->id, &data) != TNG_SUCCESS) - { - if(tng_data->current_trajectory_frame_set_input_file_pos > 0) - { - block_type_flag = TNG_TRAJECTORY_BLOCK; - } - else - { - block_type_flag = TNG_NON_TRAJECTORY_BLOCK; - } - - if(tng_data_block_create(tng_data, block_type_flag) != - TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot create particle data block. %s: %d\n", - __FILE__, __LINE__); - return(TNG_CRITICAL); - } - if(block_type_flag == TNG_TRAJECTORY_BLOCK) - { - data = &frame_set->tr_data[frame_set->n_data_blocks - 1]; - } - else - { - data = &tng_data->non_tr_data[tng_data->n_data_blocks - 1]; - } - data->block_id = block->id; - - data->block_name = malloc(strlen(block->name) + 1); - if(!data->block_name) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", - (int)strlen(block->name)+1, __FILE__, __LINE__); - return(TNG_CRITICAL); - } - strcpy(data->block_name, block->name); - - data->datatype = datatype; - - data->values = 0; - /* FIXME: Memory leak from strings. */ - data->strings = 0; - data->n_frames = 0; - data->codec_id = codec_id; - data->compression_multiplier = multiplier; - data->last_retrieved_frame = -1; - } - - n_frames_div = (n_frames % stride_length) ? n_frames / stride_length + 1 : n_frames / stride_length; + /* FIXME: Does not check if the size of the contents matches the expected + * size or if the contents can be read. */ - if(codec_id != TNG_UNCOMPRESSED) + if(tng_data_block_meta_information_read(tng_data, + &datatype, + &dependency, &sparse_data, + &n_values, &codec_id, + &first_frame_with_data, + &stride_length, &n_frames, + &num_first_particle, + &block_n_particles, + &multiplier, + hash_mode, + &md5_state) == TNG_CRITICAL) { - switch(codec_id) - { -#ifdef USE_ZLIB - case TNG_GZIP_COMPRESSION: - data_size = n_frames_div * size * n_values; - /* fprintf(stderr, "TNG library: Before compression: %"PRId64"\n", block->block_contents_size); */ - if(tng_gzip_uncompress(tng_data, block, - block->block_contents + *offset, - data_size) != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Could not read gzipped block data. %s: %d\n", __FILE__, - __LINE__); - return(TNG_CRITICAL); - } - /* fprintf(stderr, "TNG library: After compression: %"PRId64"\n", block->block_contents_size); */ - break; -#endif - } + fprintf(stderr, "TNG library: Cannot read data block (%s) meta information. %s: %d\n", + block->name, __FILE__, __LINE__); + return(TNG_CRITICAL); } - /* Allocate memory */ - if(!data->values || data->n_frames != n_frames || - data->n_values_per_frame != n_values) - { - if(tng_allocate_data_mem(tng_data, data, n_frames, stride_length, - n_values) != - TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot allocate memory for data. %s: %d\n", - __FILE__, __LINE__); - return(TNG_CRITICAL); - } - } + remaining_len = block->block_contents_size - (ftello(tng_data->input_file) - start_pos); - data->first_frame_with_data = first_frame_with_data; + stat = tng_data_read(tng_data, block, + remaining_len, + datatype, + num_first_particle, + block_n_particles, + first_frame_with_data, + stride_length, + n_frames, n_values, + codec_id, multiplier, + hash_mode, + &md5_state); - if(datatype == TNG_CHAR_DATA) + if(hash_mode == TNG_USE_HASH) { - for(i = 0; i < n_frames_div; i++) + /* If there is data left in the block that the current version of the library + * cannot interpret still read that to generate the MD5 hash. */ + tng_md5_remaining_append(tng_data, block, start_pos, &md5_state); + + md5_finish(&md5_state, (md5_byte_t *)hash); + if(strncmp(block->md5_hash, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", TNG_MD5_HASH_LEN) != 0) { - for(j = 0; j < n_values; j++) + if(strncmp(block->md5_hash, hash, TNG_MD5_HASH_LEN) != 0) { - len = tng_min_i((int)strlen(block->block_contents+*offset) + 1, - TNG_MAX_STR_LEN); - if(data->strings[i][j]) - { - free(data->strings[i][j]); - } - data->strings[i][j] = malloc(len); - if(!data->strings[i][j]) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", - len, __FILE__, __LINE__); - return(TNG_CRITICAL); - } - strncpy(data->strings[i][j], block->block_contents+*offset, - len); - *offset += len; + fprintf(stderr, "TNG library: Data block contents corrupt (%s). Hashes do not match. " + "%s: %d\n", block->name, __FILE__, __LINE__); } } } else { - memcpy(data->values, block->block_contents + *offset, - block->block_contents_size - *offset); - switch(datatype) - { - case TNG_FLOAT_DATA: - if(tng_data->input_endianness_swap_func_32) - { - for(i = 0; i < (block->block_contents_size - *offset); i+=size) - { - if(tng_data->input_endianness_swap_func_32(tng_data, - (int32_t *)((char *)data->values + i)) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - } - break; - case TNG_INT_DATA: - case TNG_DOUBLE_DATA: - if(tng_data->input_endianness_swap_func_64) - { - for(i = 0; i < (block->block_contents_size - *offset); i+=size) - { - if(tng_data->input_endianness_swap_func_64(tng_data, - (int64_t *)((char *)data->values + i)) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - } - break; - case TNG_CHAR_DATA: - break; - } + /* Seek to the end of the block */ + fseeko(tng_data->input_file, start_pos + block->block_contents_size, SEEK_SET); } - return(TNG_SUCCESS); + + return(stat); } -/** Write a non-particle data block +/* +// ** Move the blocks in a frame set so that there is no unused space between +// * them. This can only be done on the last frame set in the file and should +// * be done e.g. if the last frame set in the file has fewer frames than +// * default or after compressing data blocks in a frame set. +// * @param tng_data is a trajectory data container. +// * @details the current_trajectory_frame_set is the one that will be modified. +// * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the frame set +// * cannot be aligned or TNG_CRITICAL (2) if a major error has occured. +// * FIXME: This function is not finished!!! +// * +// static tng_function_status tng_frame_set_align(tng_trajectory_t tng_data) +// { +// tng_gen_block_t block; +// tng_trajectory_frame_set_t frame_set; +// FILE *temp = tng_data->input_file; +// int64_t pos, contents_start_pos, output_file_len; +// +// frame_set = &tng_data->current_trajectory_frame_set; +// +// if(frame_set->n_written_frames == frame_set->n_frames) +// { +// return(TNG_SUCCESS); +// } +// +// if(tng_data->current_trajectory_frame_set_output_file_pos != +// tng_data->last_trajectory_frame_set_output_file_pos) +// { +// } +// +// if(tng_output_file_init(tng_data) != TNG_SUCCESS) +// { +// fprintf(stderr, "TNG library: Cannot initialise destination file. %s: %d\n", +// __FILE__, __LINE__); +// return(TNG_CRITICAL); +// } +// +// tng_block_init(&block); +// // output_file_pos = ftello(tng_data->output_file); +// +// tng_data->input_file = tng_data->output_file; +// +// pos = tng_data->current_trajectory_frame_set_output_file_pos; +// +// fseeko(tng_data->output_file, pos, SEEK_SET); +// if(tng_block_header_read(tng_data, block) != TNG_SUCCESS) +// { +// fprintf(stderr, "TNG library: Cannot read frame set header. %s: %d\n", +// __FILE__, __LINE__); +// tng_data->input_file = temp; +// tng_block_destroy(&block); +// return(TNG_CRITICAL); +// } +// +// contents_start_pos = ftello(tng_data->output_file); +// +// fseeko(tng_data->output_file, 0, SEEK_END); +// output_file_len = ftello(tng_data->output_file); +// pos = contents_start_pos + block->block_contents_size; +// fseeko(tng_data->output_file, pos, +// SEEK_SET); +// +// while(pos < output_file_len) +// { +// if(tng_block_header_read(tng_data, block) != TNG_SUCCESS) +// { +// fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", pos, +// __FILE__, __LINE__); +// tng_data->input_file = temp; +// tng_block_destroy(&block); +// return(TNG_CRITICAL); +// } +// pos += block->header_contents_size + block->block_contents_size; +// fseeko(tng_data->output_file, pos, SEEK_SET); +// } +// +// return(TNG_SUCCESS); +// } +*/ +/** + * @brief Finish writing the current frame set. Update the number of frames + * and the hashes of the frame set and all its data blocks (if hash_mode + * == TNG_USE_HASH). * @param tng_data is a trajectory data container. - * @param block is the block to store the data (should already contain - * the block headers and the block contents). - * @param block_index is the index number of the data block in the frame set. - * @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 will be generated and written. + * @param hash_mode specifies whether to update the block md5 hash when + * updating the pointers. * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major * error has occured. */ -static tng_function_status tng_data_block_write(tng_trajectory_t tng_data, - tng_gen_block_t block, - const int64_t block_index, - const char hash_mode) +static tng_function_status tng_frame_set_finalize + (const tng_trajectory_t tng_data, + const char hash_mode) { - int64_t n_frames, stride_length, frame_step, data_start_pos; - int64_t i, j; - int offset = 0, size; - unsigned int len; -#ifdef USE_ZLIB - tng_function_status stat; -#endif - char temp, dependency, *temp_name; - double multiplier; - tng_trajectory_frame_set_t frame_set = - &tng_data->current_trajectory_frame_set; + tng_gen_block_t block; + tng_trajectory_frame_set_t frame_set; + FILE *temp = tng_data->input_file; + int64_t pos, curr_file_pos; - tng_non_particle_data_t data; - char block_type_flag; + frame_set = &tng_data->current_trajectory_frame_set; - /* If we have already started writing frame sets it is too late to write - * non-trajectory data blocks */ - if(tng_data->current_trajectory_frame_set_output_file_pos > 0) - { - block_type_flag = TNG_TRAJECTORY_BLOCK; - } - else + if(frame_set->n_written_frames == frame_set->n_frames) { - block_type_flag = TNG_NON_TRAJECTORY_BLOCK; + return(TNG_SUCCESS); } + frame_set->n_written_frames = frame_set->n_frames; + if(tng_output_file_init(tng_data) != TNG_SUCCESS) { + fprintf(stderr, "TNG library: Cannot initialise destination file. %s: %d\n", + __FILE__, __LINE__); return(TNG_CRITICAL); } - if(block_type_flag == TNG_TRAJECTORY_BLOCK) - { - data = &frame_set->tr_data[block_index]; + tng_block_init(&block); +/* output_file_pos = ftello(tng_data->output_file); */ - /* If this data block has not had any data added in this frame set - * do not write it. */ - if(data->first_frame_with_data < frame_set->first_frame) - { - return(TNG_SUCCESS); - } + tng_data->input_file = tng_data->output_file; - stride_length = tng_max_i64(1, data->stride_length); - } - else + curr_file_pos = ftello(tng_data->output_file); + + pos = tng_data->current_trajectory_frame_set_output_file_pos; + + fseeko(tng_data->output_file, pos, SEEK_SET); + + if(tng_block_header_read(tng_data, block) != TNG_SUCCESS) { - data = &tng_data->non_tr_data[block_index]; - stride_length = 1; + fprintf(stderr, "TNG library: Cannot read frame set header. %s: %d\n", + __FILE__, __LINE__); + tng_data->input_file = temp; + tng_block_destroy(&block); + return(TNG_CRITICAL); } - switch(data->datatype) +// contents_start_pos = ftello(tng_data->output_file); + + fseeko(tng_data->output_file, sizeof(frame_set->first_frame), SEEK_CUR); + if(fwrite(&frame_set->n_frames, sizeof(frame_set->n_frames), + 1, tng_data->output_file) != 1) { - case TNG_CHAR_DATA: - size = 1; - break; - case TNG_INT_DATA: - size = sizeof(int64_t); - break; - case TNG_FLOAT_DATA: - size = sizeof(float); - break; - case TNG_DOUBLE_DATA: - default: - size = sizeof(double); + tng_data->input_file = temp; + tng_block_destroy(&block); + return(TNG_CRITICAL); } - len = (unsigned int)strlen(data->block_name) + 1; - - if(!block->name || strlen(block->name) < len) + if(hash_mode == TNG_USE_HASH) { - temp_name = realloc(block->name, len); - if(!temp_name) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%u bytes). %s: %d\n", len+1, - __FILE__, __LINE__); - free(block->name); - block->name = 0; - return(TNG_CRITICAL); - } - block->name = temp_name; + tng_md5_hash_update(tng_data, block, pos, + pos + block->header_contents_size); } - strncpy(block->name, data->block_name, len); - block->id = data->block_id; - /* If writing frame independent data data->n_frames is 0, but n_frames - is used for the loop writing the data (and reserving memory) and needs - to be at least 1 */ - n_frames = tng_max_i64(1, data->n_frames); + fseeko(tng_data->output_file, curr_file_pos, SEEK_SET); - if(block_type_flag == TNG_TRAJECTORY_BLOCK) - { - /* If the frame set is finished before writing the full number of frames - make sure the data block is not longer than the frame set. */ - n_frames = tng_min_i64(n_frames, frame_set->n_frames); + tng_data->input_file = temp; + tng_block_destroy(&block); + return(TNG_SUCCESS); +} - n_frames -= (data->first_frame_with_data - frame_set->first_frame); - } +/* +// ** Sets the name of a file contents block +// * @param tng_data is a trajectory data container. +// * @param block is the block, of which to change names. +// * @param new_name is the new name of the block. +// * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major +// * error has occured. +// +// static tng_function_status tng_block_name_set(tng_trajectory_t tng_data, +// tng_gen_block_t block, +// const char *new_name) +// { +// int len; +// +// len = tng_min_size(strlen(new_name) + 1, TNG_MAX_STR_LEN); +// +// * If the currently stored string length is not enough to store the new +// * string it is freed and reallocated. * +// if(block->name && strlen(block->name) < len) +// { +// free(block->name); +// block->name = 0; +// } +// if(!block->name) +// { +// block->name = malloc(len); +// if(!block->name) +// { +// fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len, +// __FILE__, __LINE__); +// return(TNG_CRITICAL); +// } +// } +// +// strncpy(block->name, new_name, len); +// +// return(TNG_SUCCESS); +// } +*/ - frame_step = (n_frames % stride_length) ? n_frames / stride_length + 1: - n_frames / stride_length; +tng_function_status tng_atom_residue_get(const tng_trajectory_t tng_data, + const tng_atom_t atom, + tng_residue_t *residue) +{ + (void) tng_data; - /* TNG compression will use compression precision to get integers from - * floating point data. The compression multiplier stores that information - * to be able to return the precision of the compressed data. */ - if(data->codec_id == TNG_TNG_COMPRESSION) - { - data->compression_multiplier = tng_data->compression_precision; - } - /* Uncompressed data blocks do not use compression multipliers at all. - * GZip compression does not need it either. */ - else if(data->codec_id == TNG_UNCOMPRESSED || data->codec_id == TNG_GZIP_COMPRESSION) - { - data->compression_multiplier = 1.0; - } + TNG_ASSERT(atom, "TNG library: atom must not be NULL"); - if(block_type_flag == TNG_TRAJECTORY_BLOCK && data->n_frames > 0) - { - dependency = TNG_FRAME_DEPENDENT; - } - else - { - dependency = 0; - } + *residue = atom->residue; - if(tng_data_block_len_calculate(tng_data, (tng_particle_data_t)data, TNG_FALSE, n_frames, - frame_step, stride_length, 0, - 1, dependency, &data_start_pos, - &block->block_contents_size) != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot calculate length of non-particle data block. %s: %d\n", - __FILE__, __LINE__); - return(TNG_CRITICAL); - } + return(TNG_SUCCESS); +} - if(block->block_contents) - { - free(block->block_contents); - } - block->block_contents = malloc(block->block_contents_size); - if(!block->block_contents) +tng_function_status tng_atom_name_get(const tng_trajectory_t tng_data, + const tng_atom_t atom, + char *name, + const int max_len) +{ + (void) tng_data; + TNG_ASSERT(atom, "TNG library: atom must not be NULL"); + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); + + strncpy(name, atom->name, max_len - 1); + name[max_len - 1] = 0; + + if(strlen(atom->name) > (unsigned int)max_len - 1) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - block->block_contents_size, __FILE__, __LINE__); - return(TNG_CRITICAL); + return(TNG_FAILURE); } + return(TNG_SUCCESS); +} +tng_function_status tng_atom_name_set(const tng_trajectory_t tng_data, + const tng_atom_t atom, + const char *new_name) +{ + unsigned int len; + (void)tng_data; - memcpy(block->block_contents, &data->datatype, sizeof(char)); - offset += sizeof(char); + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer."); - memcpy(block->block_contents+offset, &dependency, sizeof(char)); - offset += sizeof(char); + len = tng_min_size(strlen(new_name) + 1, TNG_MAX_STR_LEN); - if(dependency & TNG_FRAME_DEPENDENT) + /* If the currently stored string length is not enough to store the new + * string it is freed and reallocated. */ + if(atom->name && strlen(atom->name) < len) { - if(stride_length > 1) - { - temp = 1; - } - else - { - temp = 0; - } - memcpy(block->block_contents+offset, &temp, sizeof(char)); - offset += sizeof(char); + free(atom->name); + atom->name = 0; } - - memcpy(block->block_contents+offset, &data->n_values_per_frame, - sizeof(data->n_values_per_frame)); - if(tng_data->output_endianness_swap_func_64) + if(!atom->name) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) + atom->name = malloc(len); + if(!atom->name) { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); + fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, + __FILE__, __LINE__); + return(TNG_CRITICAL); } } - offset += sizeof(data->n_values_per_frame); - memcpy(block->block_contents+offset, &data->codec_id, - sizeof(data->codec_id)); - if(tng_data->output_endianness_swap_func_64) + strncpy(atom->name, new_name, len); + + return(TNG_SUCCESS); +} + +tng_function_status tng_atom_type_get(const tng_trajectory_t tng_data, + const tng_atom_t atom, + char *type, + const int max_len) +{ + (void) tng_data; + TNG_ASSERT(atom, "TNG library: atom must not be NULL"); + TNG_ASSERT(type, "TNG library: type must not be a NULL pointer"); + + strncpy(type, atom->atom_type, max_len - 1); + type[max_len - 1] = 0; + + if(strlen(atom->atom_type) > (unsigned int)max_len - 1) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + return(TNG_FAILURE); } - offset += sizeof(data->codec_id); + return(TNG_SUCCESS); +} - if(data->codec_id != TNG_UNCOMPRESSED) +tng_function_status tng_atom_type_set(const tng_trajectory_t tng_data, + const tng_atom_t atom, + const char *new_type) +{ + unsigned int len; + (void)tng_data; + + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(new_type, "TNG library: new_type must not be a NULL pointer."); + + len = tng_min_size(strlen(new_type) + 1, TNG_MAX_STR_LEN); + + /* If the currently stored string length is not enough to store the new + * string it is freed and reallocated. */ + if(atom->atom_type && strlen(atom->atom_type) < len) { - memcpy(block->block_contents+offset, &data->compression_multiplier, - sizeof(data->compression_multiplier)); - if(tng_data->output_endianness_swap_func_64) - { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - offset += sizeof(data->compression_multiplier); + free(atom->atom_type); + atom->atom_type = 0; } - - if(data->n_frames > 0 && stride_length > 1) + if(!atom->atom_type) { - /* FIXME: first_frame_with_data is not reliably set */ - if(data->first_frame_with_data == 0) + atom->atom_type = malloc(len); + if(!atom->atom_type) { - data->first_frame_with_data = frame_set->first_frame; + fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, + __FILE__, __LINE__); + return(TNG_CRITICAL); } - memcpy(block->block_contents+offset, &data->first_frame_with_data, - sizeof(data->first_frame_with_data)); - if(tng_data->output_endianness_swap_func_64) - { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - offset += sizeof(data->first_frame_with_data); - - memcpy(block->block_contents+offset, &stride_length, - sizeof(data->stride_length)); - if(tng_data->output_endianness_swap_func_64) - { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)block->header_contents+offset) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - offset += sizeof(data->stride_length); } - if(data->datatype == TNG_CHAR_DATA) - { - if(data->strings) - { - for(i = 0; i < frame_step; i++) - { - for(j = 0; j < data->n_values_per_frame; j++) - { - len = (unsigned int)strlen(data->strings[i][j]) + 1; - strncpy(block->block_contents+offset, data->strings[i][j], - len); - offset += len; - } - } - } - } - else if(data->values) + strncpy(atom->atom_type, new_type, len); + + return(TNG_SUCCESS); +} + +/** + * @brief Initialise an atom struct + * @param atom is the atom to initialise. + * @return TNG_SUCCESS (0) if successful. + */ +static tng_function_status tng_atom_init(const tng_atom_t atom) +{ + atom->name = 0; + atom->atom_type = 0; + + return(TNG_SUCCESS); +} + +/** + * @brief Free the memory in an atom struct + * @param atom is the atom to destroy. + * @return TNG_SUCCESS (0) if successful. + */ +static tng_function_status tng_atom_destroy(const tng_atom_t atom) +{ + if(atom->name) { - memcpy(block->block_contents + offset, data->values, - block->block_contents_size - offset); - switch(data->datatype) - { - case TNG_FLOAT_DATA: - if(data->codec_id == TNG_UNCOMPRESSED || data-> codec_id == TNG_GZIP_COMPRESSION || - data->codec_id == TNG_TNG_COMPRESSION) - { - if(tng_data->input_endianness_swap_func_32) - { - for(i = offset; i < block->block_contents_size; i+=size) - { - if(tng_data->input_endianness_swap_func_32(tng_data, - (int32_t *)(block->block_contents + i)) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - } - } - else - { - multiplier = data->compression_multiplier; - if(fabs(multiplier - 1.0) > 0.00001 || - tng_data->input_endianness_swap_func_32) - { - for(i = offset; block->block_contents_size; i+=size) - { - *(float *)(block->block_contents + i) *= (float)multiplier; - if(tng_data->input_endianness_swap_func_32 && - tng_data->input_endianness_swap_func_32(tng_data, - (int32_t *)(block->block_contents + i)) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - } - } - break; - case TNG_INT_DATA: - if(tng_data->input_endianness_swap_func_64) - { - for(i = offset; i < block->block_contents_size; i+=size) - { - if(tng_data->input_endianness_swap_func_64(tng_data, - (int64_t *)(block->block_contents + i)) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - } - break; - case TNG_DOUBLE_DATA: - if(data->codec_id == TNG_UNCOMPRESSED || data-> codec_id == TNG_GZIP_COMPRESSION || - data->codec_id == TNG_TNG_COMPRESSION) - { - if(tng_data->input_endianness_swap_func_64) - { - for(i = offset; i < block->block_contents_size; i+=size) - { - if(tng_data->input_endianness_swap_func_64(tng_data, - (int64_t *)(block->block_contents + i)) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - } - } - else - { - multiplier = data->compression_multiplier; - if(fabs(multiplier - 1.0) > 0.00001 || - tng_data->input_endianness_swap_func_64) - { - for(i = offset; i < block->block_contents_size; i+=size) - { - *(double *)(block->block_contents + i) *= multiplier; - if(tng_data->input_endianness_swap_func_64 && - tng_data->input_endianness_swap_func_64(tng_data, - (int64_t *)(block->block_contents + i)) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - } - } - break; - case TNG_CHAR_DATA: - break; - } + free(atom->name); + atom->name = 0; } - else + if(atom->atom_type) { - memset(block->block_contents+offset, 0, block->block_contents_size - offset); + free(atom->atom_type); + atom->atom_type = 0; } - frame_set->n_written_frames += frame_set->n_unwritten_frames; - frame_set->n_unwritten_frames = 0; + return(TNG_SUCCESS); +} - if(block_type_flag == TNG_NON_TRAJECTORY_BLOCK || frame_set->n_written_frames > 0) - { - switch(data->codec_id) - { -#ifdef USE_ZLIB - case TNG_GZIP_COMPRESSION: - /* fprintf(stderr, "TNG library: Before compression: %"PRId64"\n", block->block_contents_size); */ - stat = tng_gzip_compress(tng_data, block, - block->block_contents + data_start_pos, - block->block_contents_size - data_start_pos); - if(stat != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Could not write gzipped block data. %s: %d\n", __FILE__, - __LINE__); - if(stat == TNG_CRITICAL) - { - return(TNG_CRITICAL); - } - data->codec_id = TNG_UNCOMPRESSED; - } - /* fprintf(stderr, "TNG library: After compression: %"PRId64"\n", block->block_contents_size); */ - break; -#endif - } - } +tng_function_status DECLSPECDLLEXPORT tng_version_major + (const tng_trajectory_t tng_data, + int *version) +{ + (void)tng_data; - if(tng_block_header_write(tng_data, block, hash_mode) != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot write header of file %s. %s: %d\n", - tng_data->output_file_path, __FILE__, __LINE__); - return(TNG_CRITICAL); - } + *version = TNG_VERSION_MAJOR; - if(fwrite(block->block_contents, block->block_contents_size, 1, - tng_data->output_file) != 1) - { - fprintf(stderr, "TNG library: Could not write all block data. %s: %d\n", - __FILE__, __LINE__); - return(TNG_CRITICAL); - } + return(TNG_SUCCESS); +} + +tng_function_status DECLSPECDLLEXPORT tng_version_minor + (const tng_trajectory_t tng_data, + int *version) +{ + (void)tng_data; + + *version = TNG_VERSION_MINOR; return(TNG_SUCCESS); } -/** 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). - * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major - * error has occured. - */ -static tng_function_status tng_data_block_meta_information_read - (tng_trajectory_t tng_data, - tng_gen_block_t block, - 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) +tng_function_status DECLSPECDLLEXPORT tng_version_patchlevel + (const tng_trajectory_t tng_data, + int *patch_level) { - int meta_size; - char *contents; + (void)tng_data; - if(block->block_contents) - { - contents = block->block_contents; - } - else - { - meta_size = 3 * sizeof(char) + sizeof(double) + 6 * sizeof(int64_t); - contents = malloc(meta_size); - if(!contents) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", - meta_size, __FILE__, __LINE__); - } + *patch_level = TNG_VERSION_PATCHLEVEL; - if(fread(contents, meta_size, 1, tng_data->input_file) == 0) - { - fprintf(stderr, "TNG library: Cannot read data block meta information. %s: %d\n", __FILE__, __LINE__); - free(contents); - return(TNG_CRITICAL); - } - } + return(TNG_SUCCESS); +} - memcpy(datatype, contents+*offset, - sizeof(*datatype)); - *offset += sizeof(*datatype); +tng_function_status DECLSPECDLLEXPORT tng_version + (const tng_trajectory_t tng_data, + char *version, + const int max_len) +{ + (void)tng_data; + TNG_ASSERT(version, "TNG library: version must not be a NULL pointer"); - memcpy(dependency, contents+*offset, - sizeof(*dependency)); - *offset += sizeof(*dependency); + TNG_SNPRINTF(version, max_len, "%s", TNG_VERSION); - if(*dependency & TNG_FRAME_DEPENDENT) + return(TNG_SUCCESS); +} + +tng_function_status DECLSPECDLLEXPORT tng_molecule_add + (const tng_trajectory_t tng_data, + const char *name, + tng_molecule_t *molecule) +{ + int64_t id; + + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); + + /* Set ID to the ID of the last molecule + 1 */ + if(tng_data->n_molecules) { - memcpy(sparse_data, contents+*offset, - sizeof(*sparse_data)); - *offset += sizeof(*sparse_data); + id = tng_data->molecules[tng_data->n_molecules-1].id + 1; } - - memcpy(n_values, contents+*offset, - sizeof(*n_values)); - if(tng_data->input_endianness_swap_func_64) + else { - if(tng_data->input_endianness_swap_func_64(tng_data, - n_values) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + id = 1; } - *offset += sizeof(*n_values); - 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) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - *offset += sizeof(*codec_id); + return(tng_molecule_w_id_add(tng_data, name, id, molecule)); +} - if(*codec_id != TNG_UNCOMPRESSED) - { - 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) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - *offset += sizeof(*multiplier); - } - else +tng_function_status DECLSPECDLLEXPORT tng_molecule_w_id_add + (const tng_trajectory_t tng_data, + const char *name, + const int64_t id, + tng_molecule_t *molecule) +{ + tng_molecule_t new_molecules; + int64_t *new_molecule_cnt_list; + tng_function_status stat = TNG_SUCCESS; + + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); + + new_molecules = realloc(tng_data->molecules, + sizeof(struct tng_molecule) * + (tng_data->n_molecules + 1)); + + if(!new_molecules) { - *multiplier = 1; + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", + sizeof(struct tng_molecule) * (tng_data->n_molecules + 1), + __FILE__, __LINE__); + free(tng_data->molecules); + tng_data->molecules = 0; + return(TNG_CRITICAL); } - if(*dependency & TNG_FRAME_DEPENDENT) - { - if(*sparse_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) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - *offset += sizeof(*first_frame_with_data); + new_molecule_cnt_list = realloc(tng_data->molecule_cnt_list, + sizeof(int64_t) * + (tng_data->n_molecules + 1)); - 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) - != 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 - - 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; - } - } - else + if(!new_molecule_cnt_list) { - *first_frame_with_data = 0; - *stride_length = 1; - *n_frames = 1; + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", + sizeof(int64_t) * (tng_data->n_molecules + 1), + __FILE__, __LINE__); + free(tng_data->molecule_cnt_list); + tng_data->molecule_cnt_list = 0; + free(new_molecules); + return(TNG_CRITICAL); } - if (*dependency & TNG_PARTICLE_DEPENDENT) - { - 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) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - *offset += sizeof(*num_first_particle); + tng_data->molecules = new_molecules; + tng_data->molecule_cnt_list = new_molecule_cnt_list; - 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) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - *offset += sizeof(*block_n_particles); - } + *molecule = &new_molecules[tng_data->n_molecules]; - if(!block->block_contents) - { - free(contents); - } - return(TNG_SUCCESS); + tng_molecule_init(tng_data, *molecule); + tng_molecule_name_set(tng_data, *molecule, name); + + /* FIXME: Should this be a function argument instead? */ + tng_data->molecule_cnt_list[tng_data->n_molecules] = 0; + + (*molecule)->id = id; + + tng_data->n_molecules++; + + return(stat); } -/** 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) +tng_function_status DECLSPECDLLEXPORT tng_molecule_existing_add + (const tng_trajectory_t tng_data, + tng_molecule_t *molecule_p) { - 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; + int64_t *new_molecule_cnt_list, id; + tng_molecule_t new_molecules, molecule; - if(tng_input_file_init(tng_data) != TNG_SUCCESS) + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + + /* Set ID to the ID of the last molecule + 1 */ + if(tng_data->n_molecules) { - return(TNG_CRITICAL); + id = tng_data->molecules[tng_data->n_molecules-1].id + 1; } - - if(block->block_contents) + else { - free(block->block_contents); + id = 1; } - block->block_contents = malloc(block->block_contents_size); - if(!block->block_contents) + new_molecules = realloc(tng_data->molecules, + sizeof(struct tng_molecule) * + (tng_data->n_molecules + 1)); + + if(!new_molecules) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - block->block_contents_size, __FILE__, __LINE__); + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", + sizeof(struct tng_molecule) * (tng_data->n_molecules + 1), + __FILE__, __LINE__); + free(tng_data->molecules); + tng_data->molecules = 0; 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) + new_molecule_cnt_list = realloc(tng_data->molecule_cnt_list, + sizeof(int64_t) * + (tng_data->n_molecules + 1)); + + if(!new_molecule_cnt_list) { - fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, __LINE__); + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", + sizeof(int64_t) * (tng_data->n_molecules + 1), + __FILE__, __LINE__); + free(tng_data->molecule_cnt_list); + tng_data->molecule_cnt_list = 0; + free(new_molecules); return(TNG_CRITICAL); } - /* FIXME: Does not check if the size of the contents matches the expected - * size or if the contents can be read. */ + molecule = *molecule_p; - 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); */ - } - } + tng_data->molecules = new_molecules; + tng_data->molecule_cnt_list = new_molecule_cnt_list; - 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); - } + new_molecules[tng_data->n_molecules] = *molecule; - if (dependency & TNG_PARTICLE_DEPENDENT) - { - return(tng_particle_data_read(tng_data, block, - &offset, datatype, - num_first_particle, - block_n_particles, - first_frame_with_data, - stride_length, - n_frames, n_values, - codec_id, multiplier)); - } - else + tng_data->molecule_cnt_list[tng_data->n_molecules] = 0; + + free(*molecule_p); + + molecule = &new_molecules[tng_data->n_molecules]; + + *molecule_p = molecule; + + molecule->id = id; + + tng_data->n_molecules++; + + return(TNG_SUCCESS); +} + +tng_function_status tng_molecule_name_get(const tng_trajectory_t tng_data, + const tng_molecule_t molecule, + char *name, + const int max_len) +{ + (void) tng_data; + TNG_ASSERT(molecule, "TNG library: molecule must not be NULL"); + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); + + strncpy(name, molecule->name, max_len - 1); + name[max_len - 1] = 0; + + if(strlen(molecule->name) > (unsigned int)max_len - 1) { - return(tng_data_read(tng_data, block, - &offset, datatype, - first_frame_with_data, - stride_length, - n_frames, n_values, - codec_id, multiplier)); + return(TNG_FAILURE); } + return(TNG_SUCCESS); } -/* -// ** Move the blocks in a frame set so that there is no unused space between -// * them. This can only be done on the last frame set in the file and should -// * be done e.g. if the last frame set in the file has fewer frames than -// * default or after compressing data blocks in a frame set. -// * @param tng_data is a trajectory data container. -// * @details the current_trajectory_frame_set is the one that will be modified. -// * @return TNG_SUCCESS (0) if successful, TNG_FAILURE (1) if the frame set -// * cannot be aligned or TNG_CRITICAL (2) if a major error has occured. -// * FIXME: This function is not finished!!! -// * -// static tng_function_status tng_frame_set_align(tng_trajectory_t tng_data) -// { -// tng_gen_block_t block; -// tng_trajectory_frame_set_t frame_set; -// FILE *temp = tng_data->input_file; -// int64_t pos, contents_start_pos, output_file_len; -// -// frame_set = &tng_data->current_trajectory_frame_set; -// -// if(frame_set->n_written_frames == frame_set->n_frames) -// { -// return(TNG_SUCCESS); -// } -// -// if(tng_data->current_trajectory_frame_set_output_file_pos != -// tng_data->last_trajectory_frame_set_output_file_pos) -// { -// } -// -// if(tng_output_file_init(tng_data) != TNG_SUCCESS) -// { -// fprintf(stderr, "TNG library: Cannot initialise destination file. %s: %d\n", -// __FILE__, __LINE__); -// return(TNG_CRITICAL); -// } -// -// tng_block_init(&block); -// // output_file_pos = ftello(tng_data->output_file); -// -// tng_data->input_file = tng_data->output_file; -// -// pos = tng_data->current_trajectory_frame_set_output_file_pos; -// -// fseeko(tng_data->output_file, pos, SEEK_SET); -// if(tng_block_header_read(tng_data, block) != TNG_SUCCESS) -// { -// fprintf(stderr, "TNG library: Cannot read frame set header. %s: %d\n", -// __FILE__, __LINE__); -// tng_data->input_file = temp; -// tng_block_destroy(&block); -// return(TNG_CRITICAL); -// } -// -// contents_start_pos = ftello(tng_data->output_file); -// -// fseeko(tng_data->output_file, 0, SEEK_END); -// output_file_len = ftello(tng_data->output_file); -// pos = contents_start_pos + block->block_contents_size; -// fseeko(tng_data->output_file, pos, -// SEEK_SET); -// -// while(pos < output_file_len) -// { -// if(tng_block_header_read(tng_data, block) != TNG_SUCCESS) -// { -// fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", pos, -// __FILE__, __LINE__); -// tng_data->input_file = temp; -// tng_block_destroy(&block); -// return(TNG_CRITICAL); -// } -// pos += block->header_contents_size + block->block_contents_size; -// fseeko(tng_data->output_file, pos, SEEK_SET); -// } -// -// return(TNG_SUCCESS); -// } -*/ -/** Finish writing the current frame set. Update the number of frames - * and the hashes of the frame set and all its data blocks (if hash_mode - * == TNG_USE_HASH). - * @param tng_data is a trajectory data container. - * @param hash_mode specifies whether to update the block md5 hash when - * updating the pointers. - * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major - * error has occured. - */ -static tng_function_status tng_frame_set_finalize - (tng_trajectory_t tng_data, const char hash_mode) +tng_function_status DECLSPECDLLEXPORT tng_molecule_name_set + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, + const char *new_name) { - tng_gen_block_t block; - tng_trajectory_frame_set_t frame_set; - FILE *temp = tng_data->input_file; - int64_t pos, contents_start_pos, output_file_len; + unsigned int len; + (void)tng_data; - frame_set = &tng_data->current_trajectory_frame_set; + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer."); - if(frame_set->n_written_frames == frame_set->n_frames) + len = tng_min_size(strlen(new_name) + 1, TNG_MAX_STR_LEN); + + /* If the currently stored string length is not enough to store the new + * string it is freed and reallocated. */ + if(molecule->name && strlen(molecule->name) < len) { - return(TNG_SUCCESS); + free(molecule->name); + molecule->name = 0; } - - if(tng_output_file_init(tng_data) != TNG_SUCCESS) + if(!molecule->name) { - fprintf(stderr, "TNG library: Cannot initialise destination file. %s: %d\n", - __FILE__, __LINE__); - return(TNG_CRITICAL); + molecule->name = malloc(len); + if(!molecule->name) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, + __FILE__, __LINE__); + return(TNG_CRITICAL); + } } - tng_block_init(&block); -/* output_file_pos = ftello(tng_data->output_file); */ + strncpy(molecule->name, new_name, len); - tng_data->input_file = tng_data->output_file; + return(TNG_SUCCESS); +} - pos = tng_data->current_trajectory_frame_set_output_file_pos; +tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_get + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, + int64_t *cnt) +{ + int64_t i, index = -1; - fseeko(tng_data->output_file, pos, SEEK_SET); + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(cnt, "TNG library: cnt must not be a NULL pointer."); - if(tng_block_header_read(tng_data, block) != TNG_SUCCESS) + for(i = 0; i < tng_data->n_molecules; i++) { - fprintf(stderr, "TNG library: Cannot read frame set header. %s: %d\n", - __FILE__, __LINE__); - tng_data->input_file = temp; - tng_block_destroy(&block); - return(TNG_CRITICAL); + if(&tng_data->molecules[i] == molecule) + { + index = i; + break; + } } - - contents_start_pos = ftello(tng_data->output_file); - - fseeko(tng_data->output_file, sizeof(frame_set->first_frame), SEEK_CUR); - if(fwrite(&frame_set->n_written_frames, sizeof(frame_set->n_frames), - 1, tng_data->output_file) != 1) + if(index == -1) { - tng_data->input_file = temp; - tng_block_destroy(&block); - return(TNG_CRITICAL); + return(TNG_FAILURE); } + *cnt = tng_data->molecule_cnt_list[index]; + return(TNG_SUCCESS); +} - if(hash_mode == TNG_USE_HASH) - { - tng_md5_hash_update(tng_data, block, pos, - pos + block->header_contents_size); - } +tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_set + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, + const int64_t cnt) +{ + int64_t i, old_cnt, index = -1; - fseeko(tng_data->output_file, 0, SEEK_END); - output_file_len = ftello(tng_data->output_file); - pos = contents_start_pos + block->block_contents_size; - fseeko(tng_data->output_file, pos, SEEK_SET); + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - while(pos < output_file_len) + for(i = 0; i < tng_data->n_molecules; i++) { - if(tng_block_header_read(tng_data, block) != TNG_SUCCESS) + if(&tng_data->molecules[i] == molecule) { - fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", pos, - __FILE__, __LINE__); - tng_data->input_file = temp; - tng_block_destroy(&block); - return(TNG_CRITICAL); + index = i; + break; } + } + if(index == -1) + { + fprintf(stderr, "TNG library: Could not find molecule in TNG trajectory. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + if(tng_data->var_num_atoms_flag == TNG_CONSTANT_N_ATOMS) + { + old_cnt = tng_data->molecule_cnt_list[index]; + tng_data->molecule_cnt_list[index] = cnt; - if(hash_mode == TNG_USE_HASH) - { - tng_md5_hash_update(tng_data, block, pos, - pos + block->header_contents_size); - } - pos += block->header_contents_size + block->block_contents_size; - fseeko(tng_data->output_file, pos, SEEK_SET); + tng_data->n_particles += (cnt-old_cnt) * + tng_data->molecules[index].n_atoms; + } + else + { + old_cnt = tng_data->current_trajectory_frame_set.molecule_cnt_list[index]; + tng_data->current_trajectory_frame_set.molecule_cnt_list[index] = cnt; + + tng_data->current_trajectory_frame_set.n_particles += (cnt-old_cnt) * + tng_data->molecules[index].n_atoms; } - tng_data->input_file = temp; - tng_block_destroy(&block); return(TNG_SUCCESS); } -/* -// ** Sets the name of a file contents block -// * @param tng_data is a trajectory data container. -// * @param block is the block, of which to change names. -// * @param new_name is the new name of the block. -// * @return TNG_SUCCESS (0) if successful or TNG_CRITICAL (2) if a major -// * error has occured. -// -// static tng_function_status tng_block_name_set(tng_trajectory_t tng_data, -// tng_gen_block_t block, -// const char *new_name) -// { -// int len; -// -// len = tng_min_i((int)strlen(new_name) + 1, TNG_MAX_STR_LEN); -// -// * If the currently stored string length is not enough to store the new -// * string it is freed and reallocated. * -// if(block->name && strlen(block->name) < len) -// { -// free(block->name); -// block->name = 0; -// } -// if(!block->name) -// { -// block->name = malloc(len); -// if(!block->name) -// { -// fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", len, -// __FILE__, __LINE__); -// return(TNG_CRITICAL); -// } -// } -// -// strncpy(block->name, new_name, len); -// -// return(TNG_SUCCESS); -// } -*/ - -tng_function_status tng_atom_residue_get(const tng_trajectory_t tng_data, - const tng_atom_t atom, - tng_residue_t *residue) +tng_function_status DECLSPECDLLEXPORT tng_molecule_find + (const tng_trajectory_t tng_data, + const char *name, + const int64_t nr, + tng_molecule_t *molecule) { - (void) tng_data; + int64_t i, n_molecules; - TNG_ASSERT(atom, "TNG library: atom must not be NULL"); + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); + TNG_ASSERT(molecule, "TNG library: molecule must not be a NULL pointer."); - *residue = atom->residue; + n_molecules = tng_data->n_molecules; - return(TNG_SUCCESS); + for(i = n_molecules - 1; i >= 0; i--) + { + *molecule = &tng_data->molecules[i]; + if(name[0] == 0 || strcmp(name, (*molecule)->name) == 0) + { + if(nr == -1 || nr == (*molecule)->id) + { + return(TNG_SUCCESS); + } + } + } + + *molecule = 0; + + return(TNG_FAILURE); } -tng_function_status tng_atom_name_get(const tng_trajectory_t tng_data, - const tng_atom_t atom, - char *name, - const int max_len) +tng_function_status DECLSPECDLLEXPORT tng_molecule_of_index_get + (const tng_trajectory_t tng_data, + const int64_t index, + tng_molecule_t *molecule) { - (void) tng_data; - TNG_ASSERT(atom, "TNG library: atom must not be NULL"); - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); - - strncpy(name, atom->name, max_len - 1); - name[max_len - 1] = 0; + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(molecule, "TNG library: molecule must not be a NULL pointer."); - if(strlen(atom->name) > (unsigned int)max_len - 1) + if(index >= tng_data->n_molecules) { + *molecule = 0; return(TNG_FAILURE); } + *molecule = &tng_data->molecules[index]; return(TNG_SUCCESS); } -tng_function_status tng_atom_name_set(tng_trajectory_t tng_data, - tng_atom_t atom, - const char *new_name) +tng_function_status DECLSPECDLLEXPORT tng_molecule_system_copy(const tng_trajectory_t tng_data_src, + const tng_trajectory_t tng_data_dest) { - unsigned int len; - (void)tng_data; + tng_molecule_t molecule, molecule_temp; + tng_chain_t chain, chain_temp; + tng_residue_t residue, residue_temp; + tng_atom_t atom, atom_temp; + tng_bond_t bond_temp; + tng_function_status stat; + int64_t i, j, k, l, *list_temp; - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer."); + TNG_ASSERT(tng_data_src, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(tng_data_dest, "TNG library: Trajectory container not properly setup."); - len = tng_min_i((int)strlen(new_name) + 1, TNG_MAX_STR_LEN); + for(i = 0; i < tng_data_dest->n_molecules; i++) + { + molecule = &tng_data_dest->molecules[i]; + tng_molecule_destroy(tng_data_dest, molecule); + } - /* If the currently stored string length is not enough to store the new - * string it is freed and reallocated. */ - if(atom->name && strlen(atom->name) < len) + tng_data_dest->n_molecules = 0; + tng_data_dest->n_particles = 0; + + molecule_temp = realloc(tng_data_dest->molecules, + sizeof(struct tng_molecule) * tng_data_src->n_molecules); + if(!molecule_temp) { - free(atom->name); - atom->name = 0; + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", + sizeof(struct tng_molecule) * tng_data_src->n_molecules, + __FILE__, __LINE__); + free(tng_data_dest->molecules); + tng_data_dest->molecules = 0; + return(TNG_CRITICAL); } - if(!atom->name) + list_temp = realloc(tng_data_dest->molecule_cnt_list, + sizeof(int64_t) * tng_data_src->n_molecules); + if(!list_temp) { - atom->name = malloc(len); - if(!atom->name) + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", + sizeof(int64_t) * tng_data_src->n_molecules, + __FILE__, __LINE__); + free(tng_data_dest->molecule_cnt_list); + tng_data_dest->molecule_cnt_list = 0; + free(molecule_temp); + return(TNG_CRITICAL); + } + + tng_data_dest->molecules = molecule_temp; + tng_data_dest->molecule_cnt_list = list_temp; + + for(i = 0; i < tng_data_src->n_molecules; i++) + { + molecule = &tng_data_src->molecules[i]; + stat = tng_molecule_w_id_add(tng_data_dest, molecule->name, molecule->id, + &molecule_temp); + if(stat != TNG_SUCCESS) { - fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, + fprintf(stderr, "TNG library: Cannot create new molecule to make a copy. %s: %d\n", __FILE__, __LINE__); - return(TNG_CRITICAL); + return(stat); + } + molecule_temp->quaternary_str = molecule->quaternary_str; + for(j = 0; j < molecule->n_chains; j++) + { + chain = &molecule->chains[j]; + stat = tng_molecule_chain_w_id_add(tng_data_dest, molecule_temp, + chain->name, chain->id, + &chain_temp); + if(stat != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot create new chain to make a copy. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + for(k = 0; k < chain->n_residues; k++) + { + residue = &chain->residues[k]; + stat = tng_chain_residue_w_id_add(tng_data_dest, chain_temp, + residue->name, residue->id, + &residue_temp); + if(stat != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot create new residue to make a copy. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + for(l = 0; l < residue->n_atoms; l++) + { + atom = &molecule->atoms[residue->atoms_offset + l]; + stat = tng_residue_atom_w_id_add(tng_data_dest, residue_temp, + atom->name, atom->atom_type, + atom->id, &atom_temp); + if(stat != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot create new atom to make a copy. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + } + } + } + molecule_temp->n_bonds = molecule->n_bonds; + if(molecule->n_bonds > 0) + { + bond_temp = realloc(molecule_temp->bonds, sizeof(struct tng_bond) * + molecule->n_bonds); + if(!bond_temp) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", + sizeof(struct tng_bond) * molecule->n_bonds, + __FILE__, __LINE__); + free(molecule_temp->bonds); + molecule_temp->n_bonds = 0; + return(TNG_CRITICAL); + } + molecule_temp->bonds = bond_temp; + for(j = 0; j < molecule->n_bonds; j++) + { + molecule_temp->bonds[j] = molecule->bonds[j]; + } + } + stat = tng_molecule_cnt_set(tng_data_dest, molecule_temp, + tng_data_src->molecule_cnt_list[i]); + if(stat != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot set molecule count. %s: %d.\n", + __FILE__, __LINE__); + return(stat); } } + return(TNG_SUCCESS); +} - strncpy(atom->name, new_name, len); +tng_function_status DECLSPECDLLEXPORT tng_molecule_num_chains_get + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, + int64_t *n) +{ + (void) tng_data; + TNG_ASSERT(molecule, "TNG library: molecule must not be NULL"); + TNG_ASSERT(n, "TNG library: n must not be a NULL pointer"); + + *n = molecule->n_chains; return(TNG_SUCCESS); } -tng_function_status tng_atom_type_get(const tng_trajectory_t tng_data, - const tng_atom_t atom, - char *type, - const int max_len) +tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_of_index_get + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, + const int64_t index, + tng_chain_t *chain) { (void) tng_data; - TNG_ASSERT(atom, "TNG library: atom must not be NULL"); - TNG_ASSERT(type, "TNG library: type must not be a NULL pointer"); - - strncpy(type, atom->atom_type, max_len - 1); - type[max_len - 1] = 0; + TNG_ASSERT(molecule, "TNG library: molecule must not be a NULL pointer."); + TNG_ASSERT(chain, "TNG library: chain must not be a NULL pointer."); - if(strlen(atom->atom_type) > (unsigned int)max_len - 1) + if(index >= molecule->n_chains) { + *chain = 0; return(TNG_FAILURE); } + *chain = &molecule->chains[index]; return(TNG_SUCCESS); } -tng_function_status tng_atom_type_set(tng_trajectory_t tng_data, - tng_atom_t atom, - const char *new_type) +tng_function_status DECLSPECDLLEXPORT tng_molecule_num_residues_get + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, + int64_t *n) { - unsigned int len; - (void)tng_data; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(new_type, "TNG library: new_type must not be a NULL pointer."); - - len = tng_min_i((int)strlen(new_type) + 1, TNG_MAX_STR_LEN); - - /* If the currently stored string length is not enough to store the new - * string it is freed and reallocated. */ - if(atom->atom_type && strlen(atom->atom_type) < len) - { - free(atom->atom_type); - atom->atom_type = 0; - } - if(!atom->atom_type) - { - atom->atom_type = malloc(len); - if(!atom->atom_type) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, - __FILE__, __LINE__); - return(TNG_CRITICAL); - } - } + (void) tng_data; + TNG_ASSERT(molecule, "TNG library: molecule must not be NULL"); + TNG_ASSERT(n, "TNG library: n must not be a NULL pointer"); - strncpy(atom->atom_type, new_type, len); + *n = molecule->n_residues; return(TNG_SUCCESS); } -/** Initialise an atom struct - * @param atom is the atom to initialise. - * @return TNG_SUCCESS (0) if successful. - */ -static tng_function_status tng_atom_init(tng_atom_t atom) +tng_function_status DECLSPECDLLEXPORT tng_molecule_residue_of_index_get + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, + const int64_t index, + tng_residue_t *residue) { - atom->name = 0; - atom->atom_type = 0; + (void) tng_data; + TNG_ASSERT(molecule, "TNG library: molecule must not be a NULL pointer."); + TNG_ASSERT(residue, "TNG library: residue must not be a NULL pointer."); + if(index >= molecule->n_residues) + { + *residue = 0; + return(TNG_FAILURE); + } + *residue = &molecule->residues[index]; return(TNG_SUCCESS); } -/** Free the memory in an atom struct - * @param atom is the atom to destroy. - * @return TNG_SUCCESS (0) if successful. - */ -static tng_function_status tng_atom_destroy(tng_atom_t atom) -{ - if(atom->name) - { - free(atom->name); - atom->name = 0; - } - if(atom->atom_type) - { - free(atom->atom_type); - atom->atom_type = 0; - } - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_version_major +tng_function_status DECLSPECDLLEXPORT tng_molecule_num_atoms_get (const tng_trajectory_t tng_data, - int *version) + const tng_molecule_t molecule, + int64_t *n) { - (void)tng_data; + (void) tng_data; + TNG_ASSERT(molecule, "TNG library: molecule must not be NULL"); + TNG_ASSERT(n, "TNG library: n must not be a NULL pointer"); - *version = TNG_VERSION_MAJOR; + *n = molecule->n_atoms; return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_version_minor +tng_function_status DECLSPECDLLEXPORT tng_molecule_atom_of_index_get (const tng_trajectory_t tng_data, - int *version) + const tng_molecule_t molecule, + const int64_t index, + tng_atom_t *atom) { - (void)tng_data; - - *version = TNG_VERSION_MINOR; + (void) tng_data; + TNG_ASSERT(molecule, "TNG library: molecule must not be a NULL pointer."); + TNG_ASSERT(atom, "TNG library: atom must not be a NULL pointer."); + if(index >= molecule->n_atoms) + { + *atom = 0; + return(TNG_FAILURE); + } + *atom = &molecule->atoms[index]; return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_version_patchlevel +tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_find (const tng_trajectory_t tng_data, - int *patch_level) + const tng_molecule_t molecule, + const char *name, + const int64_t nr, + tng_chain_t *chain) { + int64_t i, n_chains; (void)tng_data; - *patch_level = TNG_VERSION_PATCHLEVEL; + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); - return(TNG_SUCCESS); -} + n_chains = molecule->n_chains; -tng_function_status DECLSPECDLLEXPORT tng_version - (const tng_trajectory_t tng_data, - char *version, - const int max_len) -{ - (void)tng_data; - TNG_ASSERT(version, "TNG library: version must not be a NULL pointer"); + for(i = n_chains - 1; i >= 0; i--) + { + *chain = &molecule->chains[i]; + if(name[0] == 0 || strcmp(name, (*chain)->name) == 0) + { + if(nr == -1 || nr == (*chain)->id) + { + return(TNG_SUCCESS); + } + } + } - TNG_SNPRINTF(version, max_len, "%s", TNG_VERSION); + *chain = 0; - return(TNG_SUCCESS); + return(TNG_FAILURE); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_add - (tng_trajectory_t tng_data, +tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_add + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, const char *name, - tng_molecule_t *molecule) + tng_chain_t *chain) { int64_t id; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); - /* Set ID to the ID of the last molecule + 1 */ - if(tng_data->n_molecules) + /* Set ID to the ID of the last chain + 1 */ + if(molecule->n_chains) { - id = tng_data->molecules[tng_data->n_molecules-1].id + 1; + id = molecule->chains[molecule->n_chains-1].id + 1; } else { id = 1; } - return(tng_molecule_w_id_add(tng_data, name, id, molecule)); + return(tng_molecule_chain_w_id_add(tng_data, molecule, name, + id, chain)); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_w_id_add - (tng_trajectory_t tng_data, +tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_w_id_add + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, const char *name, const int64_t id, - tng_molecule_t *molecule) + tng_chain_t *chain) { - tng_molecule_t new_molecules; - int64_t *new_molecule_cnt_list; + tng_chain_t new_chains; tng_function_status stat = TNG_SUCCESS; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); - new_molecules = realloc(tng_data->molecules, - sizeof(struct tng_molecule) * - (tng_data->n_molecules + 1)); - - if(!new_molecules) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(struct tng_molecule) * (tng_data->n_molecules + 1), - __FILE__, __LINE__); - free(tng_data->molecules); - tng_data->molecules = 0; - return(TNG_CRITICAL); - } - - new_molecule_cnt_list = realloc(tng_data->molecule_cnt_list, - sizeof(int64_t) * - (tng_data->n_molecules + 1)); + new_chains = realloc(molecule->chains, + sizeof(struct tng_chain) * + (molecule->n_chains + 1)); - if(!new_molecule_cnt_list) + if(!new_chains) { fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(int64_t) * (tng_data->n_molecules + 1), + sizeof(struct tng_chain) * (molecule->n_chains + 1), __FILE__, __LINE__); - free(tng_data->molecule_cnt_list); - tng_data->molecule_cnt_list = 0; - free(new_molecules); + free(molecule->chains); + molecule->chains = 0; return(TNG_CRITICAL); } - tng_data->molecules = new_molecules; - tng_data->molecule_cnt_list = new_molecule_cnt_list; + molecule->chains = new_chains; - *molecule = &new_molecules[tng_data->n_molecules]; + *chain = &new_chains[molecule->n_chains]; + (*chain)->name = 0; - tng_molecule_init(tng_data, *molecule); - tng_molecule_name_set(tng_data, *molecule, name); + tng_chain_name_set(tng_data, *chain, name); - /* FIXME: Should this be a function argument instead? */ - tng_data->molecule_cnt_list[tng_data->n_molecules] = 0; + (*chain)->molecule = molecule; + (*chain)->n_residues = 0; - (*molecule)->id = id; + molecule->n_chains++; - tng_data->n_molecules++; + (*chain)->id = id; return(stat); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_existing_add - (tng_trajectory_t tng_data, - tng_molecule_t *molecule_p) +tng_function_status DECLSPECDLLEXPORT tng_molecule_bond_add + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, + const int64_t from_atom_id, + const int64_t to_atom_id, + tng_bond_t *bond) { - int64_t *new_molecule_cnt_list, id; - tng_molecule_t new_molecules, molecule; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - - /* Set ID to the ID of the last molecule + 1 */ - if(tng_data->n_molecules) - { - id = tng_data->molecules[tng_data->n_molecules-1].id + 1; - } - else - { - id = 1; - } + tng_bond_t new_bonds; + (void)tng_data; - new_molecules = realloc(tng_data->molecules, - sizeof(struct tng_molecule) * - (tng_data->n_molecules + 1)); + new_bonds = realloc(molecule->bonds, + sizeof(struct tng_bond) * + (molecule->n_bonds + 1)); - if(!new_molecules) + if(!new_bonds) { fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(struct tng_molecule) * (tng_data->n_molecules + 1), + sizeof(struct tng_bond) * (molecule->n_bonds + 1), __FILE__, __LINE__); - free(tng_data->molecules); - tng_data->molecules = 0; + *bond = 0; + free(molecule->bonds); + molecule->bonds = 0; return(TNG_CRITICAL); } - new_molecule_cnt_list = realloc(tng_data->molecule_cnt_list, - sizeof(int64_t) * - (tng_data->n_molecules + 1)); - - if(!new_molecule_cnt_list) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(int64_t) * (tng_data->n_molecules + 1), - __FILE__, __LINE__); - free(tng_data->molecule_cnt_list); - tng_data->molecule_cnt_list = 0; - free(new_molecules); - return(TNG_CRITICAL); - } + molecule->bonds = new_bonds; - molecule = *molecule_p; + *bond = &new_bonds[molecule->n_bonds]; - tng_data->molecules = new_molecules; - tng_data->molecule_cnt_list = new_molecule_cnt_list; + (*bond)->from_atom_id = from_atom_id; + (*bond)->to_atom_id = to_atom_id; - new_molecules[tng_data->n_molecules] = *molecule; + molecule->n_bonds++; - tng_data->molecule_cnt_list[tng_data->n_molecules] = 0; + return(TNG_SUCCESS); +} - free(*molecule_p); +tng_function_status DECLSPECDLLEXPORT tng_molecule_atom_find + (const tng_trajectory_t tng_data, + const tng_molecule_t molecule, + const char *name, + const int64_t id, + tng_atom_t *atom) +{ + int64_t i, n_atoms; + (void)tng_data; - molecule = &new_molecules[tng_data->n_molecules]; + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); - *molecule_p = molecule; + n_atoms = molecule->n_atoms; - molecule->id = id; + for(i = n_atoms - 1; i >= 0; i--) + { + *atom = &molecule->atoms[i]; + if(name[0] == 0 || strcmp(name, (*atom)->name) == 0) + { + if(id == -1 || id == (*atom)->id) + { + return(TNG_SUCCESS); + } + } + } - tng_data->n_molecules++; + *atom = 0; - return(TNG_SUCCESS); + return(TNG_FAILURE); } -tng_function_status tng_molecule_name_get(const tng_trajectory_t tng_data, - const tng_molecule_t molecule, - char *name, - const int max_len) -{ - (void) tng_data; - TNG_ASSERT(molecule, "TNG library: molecule must not be NULL"); +tng_function_status tng_chain_name_get(const tng_trajectory_t tng_data, + const tng_chain_t chain, + char *name, + const int max_len) +{ + (void) tng_data; + TNG_ASSERT(chain, "TNG library: chain must not be NULL"); TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); - strncpy(name, molecule->name, max_len - 1); + strncpy(name, chain->name, max_len - 1); name[max_len - 1] = 0; - if(strlen(molecule->name) > (unsigned int)max_len - 1) + if(strlen(chain->name) > (unsigned int)max_len - 1) { return(TNG_FAILURE); } return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_name_set - (tng_trajectory_t tng_data, - tng_molecule_t molecule, +tng_function_status DECLSPECDLLEXPORT tng_chain_name_set + (const tng_trajectory_t tng_data, + const tng_chain_t chain, const char *new_name) { unsigned int len; (void)tng_data; - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer."); - len = tng_min_i((int)strlen(new_name) + 1, TNG_MAX_STR_LEN); + len = tng_min_size(strlen(new_name) + 1, TNG_MAX_STR_LEN); /* If the currently stored string length is not enough to store the new * string it is freed and reallocated. */ - if(molecule->name && strlen(molecule->name) < len) + if(chain->name && strlen(chain->name) < len) { - free(molecule->name); - molecule->name = 0; + free(chain->name); + chain->name = 0; } - if(!molecule->name) + if(!chain->name) { - molecule->name = malloc(len); - if(!molecule->name) + chain->name = malloc(len); + if(!chain->name) { fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, __FILE__, __LINE__); @@ -8170,1695 +7655,1670 @@ tng_function_status DECLSPECDLLEXPORT tng_molecule_name_set } } - strncpy(molecule->name, new_name, len); + strncpy(chain->name, new_name, len); return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_get +tng_function_status DECLSPECDLLEXPORT tng_chain_num_residues_get (const tng_trajectory_t tng_data, - const tng_molecule_t molecule, - int64_t *cnt) + const tng_chain_t chain, + int64_t *n) { - int64_t i, index = -1; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(cnt, "TNG library: cnt must not be a NULL pointer."); + (void) tng_data; + TNG_ASSERT(chain, "TNG library: chain must not be NULL"); + TNG_ASSERT(n, "TNG library: n must not be a NULL pointer"); - for(i = 0; i < tng_data->n_molecules; i++) - { - if(&tng_data->molecules[i] == molecule) - { - index = i; - break; - } - } - if(index == -1) - { - return(TNG_FAILURE); - } - *cnt = tng_data->molecule_cnt_list[index]; + *n = chain->n_residues; return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_cnt_set - (tng_trajectory_t tng_data, - tng_molecule_t molecule, - const int64_t cnt) +tng_function_status DECLSPECDLLEXPORT tng_chain_residue_of_index_get + (const tng_trajectory_t tng_data, + const tng_chain_t chain, + const int64_t index, + tng_residue_t *residue) { - int64_t i, old_cnt, index = -1; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + (void) tng_data; + TNG_ASSERT(chain, "TNG library: chain must not be a NULL pointer."); + TNG_ASSERT(residue, "TNG library: residue must not be a NULL pointer."); - for(i = 0; i < tng_data->n_molecules; i++) - { - if(&tng_data->molecules[i] == molecule) - { - index = i; - break; - } - } - if(index == -1) + if(index >= chain->n_residues) { - fprintf(stderr, "TNG library: Could not find molecule in TNG trajectory. %s: %d\n", - __FILE__, __LINE__); + *residue = 0; return(TNG_FAILURE); } - if(tng_data->var_num_atoms_flag == TNG_CONSTANT_N_ATOMS) - { - old_cnt = tng_data->molecule_cnt_list[index]; - tng_data->molecule_cnt_list[index] = cnt; - - tng_data->n_particles += (cnt-old_cnt) * - tng_data->molecules[index].n_atoms; - } - else - { - old_cnt = tng_data->current_trajectory_frame_set.molecule_cnt_list[index]; - tng_data->current_trajectory_frame_set.molecule_cnt_list[index] = cnt; - - tng_data->current_trajectory_frame_set.n_particles += (cnt-old_cnt) * - tng_data->molecules[index].n_atoms; - } - + *residue = &chain->residues[index]; return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_find - (tng_trajectory_t tng_data, +tng_function_status DECLSPECDLLEXPORT tng_chain_residue_find + (const tng_trajectory_t tng_data, + const tng_chain_t chain, const char *name, - int64_t nr, - tng_molecule_t *molecule) + const int64_t id, + tng_residue_t *residue) { - int64_t i, n_molecules; + int64_t i, n_residues; + (void)tng_data; - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); - TNG_ASSERT(molecule, "TNG library: molecule must not be a NULL pointer."); - n_molecules = tng_data->n_molecules; + n_residues = chain->n_residues; - for(i = n_molecules - 1; i >= 0; i--) + for(i = n_residues - 1; i >= 0; i--) { - *molecule = &tng_data->molecules[i]; - if(name[0] == 0 || strcmp(name, (*molecule)->name) == 0) + *residue = &chain->residues[i]; + if(name[0] == 0 || strcmp(name, (*residue)->name) == 0) { - if(nr == -1 || nr == (*molecule)->id) + if(id == -1 || id == (*residue)->id) { return(TNG_SUCCESS); } } } - *molecule = 0; + *residue = 0; return(TNG_FAILURE); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_of_index_get - (tng_trajectory_t tng_data, - int64_t index, - tng_molecule_t *molecule) +tng_function_status DECLSPECDLLEXPORT tng_chain_residue_add + (const tng_trajectory_t tng_data, + const tng_chain_t chain, + const char *name, + tng_residue_t *residue) { + int64_t id; + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(molecule, "TNG library: molecule must not be a NULL pointer."); + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); - if(index >= tng_data->n_molecules) + /* Set ID to the ID of the last residue + 1 */ + if(chain->n_residues) { - *molecule = 0; - return(TNG_FAILURE); + id = chain->residues[chain->n_residues-1].id + 1; } - *molecule = &tng_data->molecules[index]; - return(TNG_SUCCESS); + else + { + id = 0; + } + + return(tng_chain_residue_w_id_add(tng_data, chain, name, + id, residue)); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_system_copy(tng_trajectory_t tng_data_src, - tng_trajectory_t tng_data_dest) +tng_function_status DECLSPECDLLEXPORT tng_chain_residue_w_id_add + (const tng_trajectory_t tng_data, + const tng_chain_t chain, + const char *name, + const int64_t id, + tng_residue_t *residue) { - tng_molecule_t molecule, molecule_temp; - tng_chain_t chain, chain_temp; - tng_residue_t residue, residue_temp; - tng_atom_t atom, atom_temp; - tng_bond_t bond_temp; - tng_function_status stat; - int64_t i, j, k, l, *list_temp; + int64_t curr_index; + tng_residue_t new_residues, temp_residue, last_residue; + tng_molecule_t molecule = chain->molecule; + tng_function_status stat = TNG_SUCCESS; - TNG_ASSERT(tng_data_src, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(tng_data_dest, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); - for(i = 0; i < tng_data_dest->n_molecules; i++) + if(chain->n_residues) { - molecule = &tng_data_dest->molecules[i]; - tng_molecule_destroy(tng_data_dest, molecule); + curr_index = chain->residues - molecule->residues; } - - tng_data_dest->n_molecules = 0; - tng_data_dest->n_particles = 0; - - molecule_temp = realloc(tng_data_dest->molecules, - sizeof(struct tng_molecule) * tng_data_src->n_molecules); - if(!molecule_temp) + else { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(struct tng_molecule) * tng_data_src->n_molecules, - __FILE__, __LINE__); - free(tng_data_dest->molecules); - tng_data_dest->molecules = 0; - return(TNG_CRITICAL); + curr_index = -1; } - list_temp = realloc(tng_data_dest->molecule_cnt_list, - sizeof(int64_t) * tng_data_src->n_molecules); - if(!list_temp) + + new_residues = realloc(molecule->residues, + sizeof(struct tng_residue) * + (molecule->n_residues + 1)); + + if(!new_residues) { fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(int64_t) * tng_data_src->n_molecules, + sizeof(struct tng_residue) * (molecule->n_residues + 1), __FILE__, __LINE__); - free(tng_data_dest->molecule_cnt_list); - tng_data_dest->molecule_cnt_list = 0; - free(molecule_temp); + free(molecule->residues); + molecule->residues = 0; return(TNG_CRITICAL); } - tng_data_dest->molecules = molecule_temp; - tng_data_dest->molecule_cnt_list = list_temp; + molecule->residues = new_residues; - for(i = 0; i < tng_data_src->n_molecules; i++) + if(curr_index != -1) { - molecule = &tng_data_src->molecules[i]; - stat = tng_molecule_w_id_add(tng_data_dest, molecule->name, molecule->id, - &molecule_temp); - if(stat != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot create new molecule to make a copy. %s: %d\n", - __FILE__, __LINE__); - return(stat); - } - molecule_temp->quaternary_str = molecule->quaternary_str; - for(j = 0; j < molecule->n_chains; j++) + chain->residues = new_residues + curr_index; + if(molecule->n_residues) { - chain = &molecule->chains[j]; - stat = tng_molecule_chain_w_id_add(tng_data_dest, molecule_temp, - chain->name, chain->id, - &chain_temp); - if(stat != TNG_SUCCESS) + last_residue = &new_residues[molecule->n_residues - 1]; + + temp_residue = chain->residues + (chain->n_residues - 1); + /* Make space in list of residues to add the new residues together with the other + * residues of this chain */ + if(temp_residue != last_residue) { - fprintf(stderr, "TNG library: Cannot create new chain to make a copy. %s: %d\n", - __FILE__, __LINE__); - return(stat); + ++temp_residue; + memmove(temp_residue + 1, temp_residue, + last_residue - temp_residue); } - for(k = 0; k < chain->n_residues; k++) - { - residue = &chain->residues[k]; - stat = tng_chain_residue_w_id_add(tng_data_dest, chain_temp, - residue->name, residue->id, - &residue_temp); - if(stat != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot create new residue to make a copy. %s: %d\n", - __FILE__, __LINE__); - return(stat); - } - for(l = 0; l < residue->n_atoms; l++) - { - atom = &molecule->atoms[residue->atoms_offset + l]; - stat = tng_residue_atom_w_id_add(tng_data_dest, residue_temp, - atom->name, atom->atom_type, - atom->id, &atom_temp); - if(stat != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot create new atom to make a copy. %s: %d\n", - __FILE__, __LINE__); - return(stat); - } - } - } - } - molecule_temp->n_bonds = molecule->n_bonds; - if(molecule->n_bonds > 0) - { - bond_temp = realloc(molecule_temp->bonds, sizeof(struct tng_bond) * - molecule->n_bonds); - if(!bond_temp) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(struct tng_bond) * molecule->n_bonds, - __FILE__, __LINE__); - free(molecule_temp->bonds); - molecule_temp->n_bonds = 0; - return(TNG_CRITICAL); - } - molecule_temp->bonds = bond_temp; - for(j = 0; j < molecule->n_bonds; j++) - { - molecule_temp->bonds[j] = molecule->bonds[j]; - } - } - stat = tng_molecule_cnt_set(tng_data_dest, molecule_temp, - tng_data_src->molecule_cnt_list[i]); - if(stat != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot set molecule count. %s: %d.\n", - __FILE__, __LINE__); - return(stat); } } - return(TNG_SUCCESS); -} + else + { + curr_index = molecule->n_residues; + } -tng_function_status DECLSPECDLLEXPORT tng_molecule_num_chains_get - (const tng_trajectory_t tng_data, - const tng_molecule_t molecule, - int64_t *n) -{ - (void) tng_data; - TNG_ASSERT(molecule, "TNG library: molecule must not be NULL"); - TNG_ASSERT(n, "TNG library: n must not be a NULL pointer"); + *residue = &molecule->residues[curr_index + chain->n_residues]; - *n = molecule->n_chains; + if(!chain->n_residues) + { + chain->residues = *residue; + } + else + { + chain->residues = &molecule->residues[curr_index]; + } - return(TNG_SUCCESS); + (*residue)->name = 0; + tng_residue_name_set(tng_data, *residue, name); + + (*residue)->chain = chain; + (*residue)->n_atoms = 0; + (*residue)->atoms_offset = 0; + + chain->n_residues++; + molecule->n_residues++; + + (*residue)->id = id; + + return(stat); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_of_index_get - (tng_trajectory_t tng_data, - tng_molecule_t molecule, - int64_t index, - tng_chain_t *chain) +tng_function_status tng_residue_name_get(const tng_trajectory_t tng_data, + const tng_residue_t residue, + char *name, + const int max_len) { (void) tng_data; - TNG_ASSERT(molecule, "TNG library: molecule must not be a NULL pointer."); - TNG_ASSERT(chain, "TNG library: chain must not be a NULL pointer."); + TNG_ASSERT(residue, "TNG library: residue must not be NULL"); + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); - if(index >= molecule->n_chains) + strncpy(name, residue->name, max_len - 1); + name[max_len - 1] = 0; + + if(strlen(residue->name) > (unsigned int)max_len - 1) { - *chain = 0; return(TNG_FAILURE); } - *chain = &molecule->chains[index]; return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_num_residues_get - (const tng_trajectory_t tng_data, - const tng_molecule_t molecule, - int64_t *n) +tng_function_status DECLSPECDLLEXPORT tng_residue_name_set(const tng_trajectory_t tng_data, + const tng_residue_t residue, + const char *new_name) { - (void) tng_data; - TNG_ASSERT(molecule, "TNG library: molecule must not be NULL"); - TNG_ASSERT(n, "TNG library: n must not be a NULL pointer"); - - *n = molecule->n_residues; + unsigned int len; + (void)tng_data; - return(TNG_SUCCESS); -} + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer"); -tng_function_status DECLSPECDLLEXPORT tng_molecule_residue_of_index_get - (const tng_trajectory_t tng_data, - const tng_molecule_t molecule, - const int64_t index, - tng_residue_t *residue) -{ - (void) tng_data; - TNG_ASSERT(molecule, "TNG library: molecule must not be a NULL pointer."); - TNG_ASSERT(residue, "TNG library: residue must not be a NULL pointer."); + len = tng_min_size(strlen(new_name) + 1, TNG_MAX_STR_LEN); - if(index >= molecule->n_residues) + /* If the currently stored string length is not enough to store the new + * string it is freed and reallocated. */ + if(residue->name && strlen(residue->name) < len) { - *residue = 0; - return(TNG_FAILURE); + free(residue->name); + residue->name = 0; } - *residue = &molecule->residues[index]; + if(!residue->name) + { + residue->name = malloc(len); + if(!residue->name) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, + __FILE__, __LINE__); + return(TNG_CRITICAL); + } + } + + strncpy(residue->name, new_name, len); + return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_num_atoms_get +tng_function_status DECLSPECDLLEXPORT tng_residue_num_atoms_get (const tng_trajectory_t tng_data, - const tng_molecule_t molecule, + const tng_residue_t residue, int64_t *n) { (void) tng_data; - TNG_ASSERT(molecule, "TNG library: molecule must not be NULL"); + TNG_ASSERT(residue, "TNG library: residue must not be NULL"); TNG_ASSERT(n, "TNG library: n must not be a NULL pointer"); - *n = molecule->n_atoms; + *n = residue->n_atoms; return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_atom_of_index_get +tng_function_status DECLSPECDLLEXPORT tng_residue_atom_of_index_get (const tng_trajectory_t tng_data, - const tng_molecule_t molecule, + const tng_residue_t residue, const int64_t index, tng_atom_t *atom) { + tng_chain_t chain; + tng_molecule_t molecule; + (void) tng_data; - TNG_ASSERT(molecule, "TNG library: molecule must not be a NULL pointer."); + TNG_ASSERT(residue, "TNG library: residue must not be a NULL pointer."); TNG_ASSERT(atom, "TNG library: atom must not be a NULL pointer."); - if(index >= molecule->n_atoms) + if(index >= residue->n_atoms) { *atom = 0; return(TNG_FAILURE); } - *atom = &molecule->atoms[index]; - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_find - (tng_trajectory_t tng_data, - tng_molecule_t molecule, - const char *name, - int64_t nr, - tng_chain_t *chain) -{ - int64_t i, n_chains; - (void)tng_data; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); - - n_chains = molecule->n_chains; + chain = residue->chain; + molecule = chain->molecule; - for(i = n_chains - 1; i >= 0; i--) + if(index + residue->atoms_offset >= molecule->n_atoms) { - *chain = &molecule->chains[i]; - if(name[0] == 0 || strcmp(name, (*chain)->name) == 0) - { - if(nr == -1 || nr == (*chain)->id) - { - return(TNG_SUCCESS); - } - } + *atom = 0; + return(TNG_FAILURE); } - *chain = 0; - - return(TNG_FAILURE); + *atom = &molecule->atoms[residue->atoms_offset + index]; + return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_add - (tng_trajectory_t tng_data, - tng_molecule_t molecule, - const char *name, - tng_chain_t *chain) +tng_function_status DECLSPECDLLEXPORT tng_residue_atom_add + (const tng_trajectory_t tng_data, + const tng_residue_t residue, + const char *atom_name, + const char *atom_type, + tng_atom_t *atom) { int64_t id; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); + TNG_ASSERT(atom_name, "TNG library: atom_name must not be a NULL pointer."); + TNG_ASSERT(atom_type, "TNG library: atom_type must not be a NULL pointer."); - /* Set ID to the ID of the last chain + 1 */ - if(molecule->n_chains) + /* Set ID to the ID of the last atom + 1 */ + if(residue->chain->molecule->n_atoms) { - id = molecule->chains[molecule->n_chains-1].id + 1; + id = residue->chain->molecule->atoms[residue->chain->molecule->n_atoms-1].id + 1; } else { - id = 1; + id = 0; } - return(tng_molecule_chain_w_id_add(tng_data, molecule, name, - id, chain)); + return(tng_residue_atom_w_id_add(tng_data, residue, atom_name, atom_type, + id, atom)); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_chain_w_id_add - (tng_trajectory_t tng_data, - tng_molecule_t molecule, - const char *name, +tng_function_status DECLSPECDLLEXPORT tng_residue_atom_w_id_add + (const tng_trajectory_t tng_data, + const tng_residue_t residue, + const char *atom_name, + const char *atom_type, const int64_t id, - tng_chain_t *chain) + tng_atom_t *atom) { - tng_chain_t new_chains; + tng_atom_t new_atoms; + tng_molecule_t molecule = residue->chain->molecule; tng_function_status stat = TNG_SUCCESS; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); - - new_chains = realloc(molecule->chains, - sizeof(struct tng_chain) * - (molecule->n_chains + 1)); + TNG_ASSERT(atom_name, "TNG library: atom_name must not be a NULL pointer."); + TNG_ASSERT(atom_type, "TNG library: atom_type must not be a NULL pointer."); - if(!new_chains) + if(!residue->n_atoms) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(struct tng_chain) * (molecule->n_chains + 1), - __FILE__, __LINE__); - free(molecule->chains); - molecule->chains = 0; - return(TNG_CRITICAL); + residue->atoms_offset = molecule->n_atoms; } - molecule->chains = new_chains; + new_atoms = realloc(molecule->atoms, + sizeof(struct tng_atom) * + (molecule->n_atoms + 1)); - *chain = &new_chains[molecule->n_chains]; - (*chain)->name = 0; + if(!new_atoms) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", + sizeof(struct tng_atom) * (molecule->n_atoms + 1), + __FILE__, __LINE__); + free(molecule->atoms); + molecule->atoms = 0; + return(TNG_CRITICAL); + } - tng_chain_name_set(tng_data, *chain, name); + molecule->atoms = new_atoms; - (*chain)->molecule = molecule; - (*chain)->n_residues = 0; + *atom = &new_atoms[molecule->n_atoms]; - molecule->n_chains++; + tng_atom_init(*atom); + tng_atom_name_set(tng_data, *atom, atom_name); + tng_atom_type_set(tng_data, *atom, atom_type); - (*chain)->id = id; + (*atom)->residue = residue; + + residue->n_atoms++; + molecule->n_atoms++; + + (*atom)->id = id; return(stat); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_bond_add - (const tng_trajectory_t tng_data, - tng_molecule_t molecule, - const int64_t from_atom_id, - const int64_t to_atom_id, - tng_bond_t *bond) +tng_function_status DECLSPECDLLEXPORT tng_molecule_alloc(const tng_trajectory_t tng_data, + tng_molecule_t *molecule_p) { - tng_bond_t new_bonds; - (void)tng_data; + *molecule_p = malloc(sizeof(struct tng_molecule)); + if(!*molecule_p) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n", + sizeof(struct tng_molecule), __FILE__, __LINE__); + return(TNG_CRITICAL); + } - new_bonds = realloc(molecule->bonds, - sizeof(struct tng_bond) * - (molecule->n_bonds + 1)); + tng_molecule_init(tng_data, *molecule_p); - if(!new_bonds) + return(TNG_SUCCESS); +} + +tng_function_status DECLSPECDLLEXPORT tng_molecule_free(const tng_trajectory_t tng_data, + tng_molecule_t *molecule_p) +{ + if(!*molecule_p) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(struct tng_bond) * (molecule->n_bonds + 1), - __FILE__, __LINE__); - *bond = 0; - free(molecule->bonds); - molecule->bonds = 0; - return(TNG_CRITICAL); + return(TNG_SUCCESS); } - molecule->bonds = new_bonds; + tng_molecule_destroy(tng_data, *molecule_p); - *bond = &new_bonds[molecule->n_bonds]; + free(*molecule_p); + *molecule_p = 0; - (*bond)->from_atom_id = from_atom_id; - (*bond)->to_atom_id = to_atom_id; + return(TNG_SUCCESS); +} - molecule->n_bonds++; +tng_function_status DECLSPECDLLEXPORT tng_molecule_init(const tng_trajectory_t tng_data, + const tng_molecule_t molecule) +{ + (void)tng_data; + molecule->quaternary_str = 1; + molecule->name = 0; + molecule->n_chains = 0; + molecule->chains = 0; + molecule->n_residues = 0; + molecule->residues = 0; + molecule->n_atoms = 0; + molecule->atoms = 0; + molecule->n_bonds = 0; + molecule->bonds = 0; return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_atom_find - (tng_trajectory_t tng_data, - tng_molecule_t molecule, - const char *name, - int64_t id, - tng_atom_t *atom) +tng_function_status DECLSPECDLLEXPORT tng_molecule_destroy(const tng_trajectory_t tng_data, + const tng_molecule_t molecule) { - int64_t i, n_atoms; + int64_t i; (void)tng_data; - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); + if(molecule->name) + { + free(molecule->name); + molecule->name = 0; + } - n_atoms = molecule->n_atoms; + if(molecule->chains) + { + for(i = 0; i < molecule->n_chains; i++) + { + if(molecule->chains[i].name) + { + free(molecule->chains[i].name); + molecule->chains[i].name = 0; + } + } + free(molecule->chains); + molecule->chains = 0; + } + molecule->n_chains = 0; - for(i = n_atoms - 1; i >= 0; i--) + if(molecule->residues) { - *atom = &molecule->atoms[i]; - if(name[0] == 0 || strcmp(name, (*atom)->name) == 0) + for(i = 0; i < molecule->n_residues; i++) { - if(id == -1 || id == (*atom)->id) + if(molecule->residues[i].name) { - return(TNG_SUCCESS); + free(molecule->residues[i].name); + molecule->residues[i].name = 0; } } + free(molecule->residues); + molecule->residues = 0; } + molecule->n_residues = 0; - *atom = 0; + if(molecule->atoms) + { + for(i = 0; i < molecule->n_atoms; i++) + { + tng_atom_destroy(&molecule->atoms[i]); + } + free(molecule->atoms); + molecule->atoms = 0; + } + molecule->n_atoms = 0; - return(TNG_FAILURE); + if(molecule->bonds) + { + free(molecule->bonds); + molecule->bonds = 0; + } + molecule->n_bonds = 0; + + return(TNG_SUCCESS); } -tng_function_status tng_chain_name_get(const tng_trajectory_t tng_data, - const tng_chain_t chain, - char *name, - const int max_len) +tng_function_status DECLSPECDLLEXPORT tng_molecule_name_of_particle_nr_get + (const tng_trajectory_t tng_data, + const int64_t nr, + char *name, + const int max_len) { - (void) tng_data; - TNG_ASSERT(chain, "TNG library: chain must not be NULL"); - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); + int64_t cnt = 0, i, *molecule_cnt_list = 0; + tng_molecule_t mol; + tng_bool found = TNG_FALSE; - strncpy(name, chain->name, max_len - 1); + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); + + tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); + + if(!molecule_cnt_list) + { + return(TNG_FAILURE); + } + + for(i = 0; i < tng_data->n_molecules; i++) + { + mol = &tng_data->molecules[i]; + if(cnt + mol->n_atoms * molecule_cnt_list[i] - 1 < nr) + { + cnt += mol->n_atoms * molecule_cnt_list[i]; + continue; + } + found = TNG_TRUE; + break; + } + if(!found) + { + return(TNG_FAILURE); + } + + strncpy(name, mol->name, max_len - 1); name[max_len - 1] = 0; - if(strlen(chain->name) > (unsigned int)max_len - 1) + if(strlen(mol->name) > (unsigned int)max_len - 1) { return(TNG_FAILURE); } return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_chain_name_set - (tng_trajectory_t tng_data, - tng_chain_t chain, - const char *new_name) +tng_function_status DECLSPECDLLEXPORT tng_molecule_id_of_particle_nr_get + (const tng_trajectory_t tng_data, + const int64_t nr, + int64_t *id) { - unsigned int len; - (void)tng_data; + int64_t cnt = 0, i, *molecule_cnt_list = 0; + tng_molecule_t mol; + tng_bool found = TNG_FALSE; - TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer."); + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(id, "TNG library: id must not be a NULL pointer."); - len = tng_min_i((int)strlen(new_name) + 1, TNG_MAX_STR_LEN); + tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); - /* If the currently stored string length is not enough to store the new - * string it is freed and reallocated. */ - if(chain->name && strlen(chain->name) < len) + if(!molecule_cnt_list) { - free(chain->name); - chain->name = 0; + return(TNG_FAILURE); } - if(!chain->name) + + for(i = 0; i < tng_data->n_molecules; i++) { - chain->name = malloc(len); - if(!chain->name) + mol = &tng_data->molecules[i]; + if(cnt + mol->n_atoms * molecule_cnt_list[i] - 1 < nr) { - fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, - __FILE__, __LINE__); - return(TNG_CRITICAL); + cnt += mol->n_atoms * molecule_cnt_list[i]; + continue; } + found = TNG_TRUE; + break; + } + if(!found) + { + return(TNG_FAILURE); } - strncpy(chain->name, new_name, len); + *id = mol->id; return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_chain_num_residues_get +tng_function_status DECLSPECDLLEXPORT tng_molsystem_bonds_get (const tng_trajectory_t tng_data, - const tng_chain_t chain, - int64_t *n) + int64_t *n_bonds, + int64_t **from_atoms, + int64_t **to_atoms) { - (void) tng_data; - TNG_ASSERT(chain, "TNG library: chain must not be NULL"); - TNG_ASSERT(n, "TNG library: n must not be a NULL pointer"); - - *n = chain->n_residues; + int64_t atom_cnt = 0, cnt, mol_cnt, i, j, k; + int64_t from_atom, to_atom, *molecule_cnt_list = 0; + tng_molecule_t mol; + tng_bond_t bond; - return(TNG_SUCCESS); -} + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(n_bonds, "TNG library: n_bonds must not be a NULL pointer."); + TNG_ASSERT(from_atoms, "TNG library: from_atoms must not be a NULL pointer."); + TNG_ASSERT(to_atoms, "TNG library: to_atoms must not be a NULL pointer."); -tng_function_status DECLSPECDLLEXPORT tng_chain_residue_of_index_get - (const tng_trajectory_t tng_data, - const tng_chain_t chain, - const int64_t index, - tng_residue_t *residue) -{ - (void) tng_data; - TNG_ASSERT(chain, "TNG library: chain must not be a NULL pointer."); - TNG_ASSERT(residue, "TNG library: residue must not be a NULL pointer."); + tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); - if(index >= chain->n_residues) + if(!molecule_cnt_list) { - *residue = 0; return(TNG_FAILURE); } - *residue = &chain->residues[index]; - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_chain_residue_find - (tng_trajectory_t tng_data, - tng_chain_t chain, - const char *name, - int64_t id, - tng_residue_t *residue) -{ - int64_t i, n_residues; - (void)tng_data; - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); + *n_bonds = 0; + /* First count the total number of bonds to allocate memory */ + for(i = 0; i < tng_data->n_molecules; i++) + { + mol = &tng_data->molecules[i]; + mol_cnt = molecule_cnt_list[i]; + *n_bonds += mol_cnt * mol->n_bonds; + } + if(*n_bonds == 0) + { + return(TNG_SUCCESS); + } - n_residues = chain->n_residues; + *from_atoms = malloc(sizeof(int64_t) * (*n_bonds)); + if(!*from_atoms) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", + sizeof(int64_t) * (*n_bonds), __FILE__, __LINE__); + return(TNG_CRITICAL); + } + *to_atoms = malloc(sizeof(int64_t) * (*n_bonds)); + if(!*to_atoms) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", + sizeof(int64_t) * (*n_bonds), __FILE__, __LINE__); + free(*from_atoms); + *from_atoms = 0; + return(TNG_CRITICAL); + } - for(i = n_residues - 1; i >= 0; i--) + cnt = 0; + for(i = 0; i < tng_data->n_molecules; i++) { - *residue = &chain->residues[i]; - if(name[0] == 0 || strcmp(name, (*residue)->name) == 0) + mol = &tng_data->molecules[i]; + mol_cnt = molecule_cnt_list[i]; + for(j = 0; j < mol_cnt; j++) { - if(id == -1 || id == (*residue)->id) + for(k = 0; k < mol->n_bonds; k++) { - return(TNG_SUCCESS); + bond = &mol->bonds[k]; + from_atom = atom_cnt + bond->from_atom_id; + to_atom = atom_cnt + bond->to_atom_id; + (*from_atoms)[cnt] = from_atom; + (*to_atoms)[cnt++] = to_atom; } + atom_cnt += mol->n_atoms; } } - *residue = 0; - - return(TNG_FAILURE); + return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_chain_residue_add - (tng_trajectory_t tng_data, - tng_chain_t chain, - const char *name, - tng_residue_t *residue) +tng_function_status DECLSPECDLLEXPORT tng_chain_name_of_particle_nr_get + (const tng_trajectory_t tng_data, + const int64_t nr, + char *name, + const int max_len) { - int64_t id; + int64_t cnt = 0, i, *molecule_cnt_list = 0; + tng_molecule_t mol; + tng_atom_t atom; + tng_bool found = TNG_FALSE; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); - /* Set ID to the ID of the last residue + 1 */ - if(chain->n_residues) + tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); + + if(!molecule_cnt_list) { - id = chain->residues[chain->n_residues-1].id + 1; + return(TNG_FAILURE); } - else + + for(i = 0; i < tng_data->n_molecules; i++) { - id = 0; + mol = &tng_data->molecules[i]; + if(cnt + mol->n_atoms * molecule_cnt_list[i] - 1 < nr) + { + cnt += mol->n_atoms * molecule_cnt_list[i]; + continue; + } + atom = &mol->atoms[nr % mol->n_atoms]; + found = TNG_TRUE; + break; + } + if(!found) + { + return(TNG_FAILURE); + } + if(!atom->residue || !atom->residue->chain) + { + return(TNG_FAILURE); } - return(tng_chain_residue_w_id_add(tng_data, chain, name, - id, residue)); + strncpy(name, atom->residue->chain->name, max_len - 1); + name[max_len - 1] = 0; + + if(strlen(atom->residue->chain->name) > (unsigned int)max_len - 1) + { + return(TNG_FAILURE); + } + return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_chain_residue_w_id_add - (tng_trajectory_t tng_data, - tng_chain_t chain, - const char *name, - const int64_t id, - tng_residue_t *residue) +tng_function_status DECLSPECDLLEXPORT tng_residue_name_of_particle_nr_get + (const tng_trajectory_t tng_data, + const int64_t nr, + char *name, + const int max_len) { - int64_t curr_index; - tng_residue_t new_residues, temp_residue, last_residue; - tng_molecule_t molecule = chain->molecule; - tng_function_status stat = TNG_SUCCESS; + int64_t cnt = 0, i, *molecule_cnt_list = 0; + tng_molecule_t mol; + tng_atom_t atom; + tng_bool found = TNG_FALSE; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); - if(chain->n_residues) - { - curr_index = chain->residues - molecule->residues; - } - else - { - curr_index = -1; - } - - new_residues = realloc(molecule->residues, - sizeof(struct tng_residue) * - (molecule->n_residues + 1)); + tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); - if(!new_residues) + if(!molecule_cnt_list) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(struct tng_residue) * (molecule->n_residues + 1), - __FILE__, __LINE__); - free(molecule->residues); - molecule->residues = 0; - return(TNG_CRITICAL); + return(TNG_FAILURE); } - molecule->residues = new_residues; - - if(curr_index != -1) + for(i = 0; i < tng_data->n_molecules; i++) { - chain->residues = new_residues + curr_index; - if(molecule->n_residues) + mol = &tng_data->molecules[i]; + if(cnt + mol->n_atoms * molecule_cnt_list[i] - 1 < nr) { - last_residue = &new_residues[molecule->n_residues - 1]; - - temp_residue = chain->residues + (chain->n_residues - 1); - /* Make space in list of residues to add the new residues together with the other - * residues of this chain */ - if(temp_residue != last_residue) - { - ++temp_residue; - memmove(temp_residue + 1, temp_residue, - last_residue - temp_residue); - } + cnt += mol->n_atoms * molecule_cnt_list[i]; + continue; } + atom = &mol->atoms[nr % mol->n_atoms]; + found = TNG_TRUE; + break; } - else - { - curr_index = molecule->n_residues; - } - - *residue = &molecule->residues[curr_index + chain->n_residues]; - - if(!chain->n_residues) + if(!found) { - chain->residues = *residue; + return(TNG_FAILURE); } - else + if(!atom->residue) { - chain->residues = &molecule->residues[curr_index]; + return(TNG_FAILURE); } - (*residue)->name = 0; - tng_residue_name_set(tng_data, *residue, name); - - (*residue)->chain = chain; - (*residue)->n_atoms = 0; - (*residue)->atoms_offset = 0; - - chain->n_residues++; - molecule->n_residues++; - - (*residue)->id = id; - - return(stat); -} - -tng_function_status tng_residue_name_get(const tng_trajectory_t tng_data, - const tng_residue_t residue, - char *name, - const int max_len) -{ - (void) tng_data; - TNG_ASSERT(residue, "TNG library: residue must not be NULL"); - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); - - strncpy(name, residue->name, max_len - 1); + strncpy(name, atom->residue->name, max_len - 1); name[max_len - 1] = 0; - if(strlen(residue->name) > (unsigned int)max_len - 1) + if(strlen(atom->residue->name) > (unsigned int)max_len - 1) { return(TNG_FAILURE); } return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_residue_name_set(tng_trajectory_t tng_data, - tng_residue_t residue, - const char *new_name) +tng_function_status DECLSPECDLLEXPORT tng_residue_id_of_particle_nr_get + (const tng_trajectory_t tng_data, + const int64_t nr, + int64_t *id) { - unsigned int len; - (void)tng_data; + int64_t cnt = 0, i, *molecule_cnt_list = 0; + tng_molecule_t mol; + tng_atom_t atom; + tng_bool found = TNG_FALSE; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer"); + TNG_ASSERT(id, "TNG library: id must not be a NULL pointer."); - len = tng_min_i((int)strlen(new_name) + 1, TNG_MAX_STR_LEN); + tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); - /* If the currently stored string length is not enough to store the new - * string it is freed and reallocated. */ - if(residue->name && strlen(residue->name) < len) + if(!molecule_cnt_list) { - free(residue->name); - residue->name = 0; + return(TNG_FAILURE); } - if(!residue->name) + + for(i = 0; i < tng_data->n_molecules; i++) { - residue->name = malloc(len); - if(!residue->name) + mol = &tng_data->molecules[i]; + if(cnt + mol->n_atoms * molecule_cnt_list[i] - 1 < nr) { - fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, - __FILE__, __LINE__); - return(TNG_CRITICAL); + cnt += mol->n_atoms * molecule_cnt_list[i]; + continue; } + atom = &mol->atoms[nr % mol->n_atoms]; + found = TNG_TRUE; + break; + } + if(!found) + { + return(TNG_FAILURE); + } + if(!atom->residue) + { + return(TNG_FAILURE); } - strncpy(residue->name, new_name, len); + *id = atom->residue->id; return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_residue_num_atoms_get +tng_function_status DECLSPECDLLEXPORT tng_global_residue_id_of_particle_nr_get (const tng_trajectory_t tng_data, - const tng_residue_t residue, - int64_t *n) + const int64_t nr, + int64_t *id) { - (void) tng_data; - TNG_ASSERT(residue, "TNG library: residue must not be NULL"); - TNG_ASSERT(n, "TNG library: n must not be a NULL pointer"); + int64_t cnt = 0, i, offset = 0, *molecule_cnt_list = 0; + tng_molecule_t mol; + tng_atom_t atom; + tng_bool found = TNG_FALSE; - *n = residue->n_atoms; + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(id, "TNG library: id must not be a NULL pointer."); + + tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); + + if(!molecule_cnt_list) + { + return(TNG_FAILURE); + } + + for(i = 0; i < tng_data->n_molecules; i++) + { + mol = &tng_data->molecules[i]; + if(cnt + mol->n_atoms * molecule_cnt_list[i] - 1 < nr) + { + cnt += mol->n_atoms * molecule_cnt_list[i]; + offset += mol->n_residues * molecule_cnt_list[i]; + continue; + } + atom = &mol->atoms[nr % mol->n_atoms]; + found = TNG_TRUE; + break; + } + if(!found) + { + return(TNG_FAILURE); + } + if(!atom->residue) + { + return(TNG_FAILURE); + } + + offset += mol->n_residues * ((nr - cnt) / mol->n_atoms); + + *id = atom->residue->id + offset; return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_residue_atom_of_index_get +tng_function_status DECLSPECDLLEXPORT tng_atom_name_of_particle_nr_get (const tng_trajectory_t tng_data, - const tng_residue_t residue, - const int64_t index, - tng_atom_t *atom) + const int64_t nr, + char *name, + const int max_len) { - tng_chain_t chain; - tng_molecule_t molecule; + int64_t cnt = 0, i, *molecule_cnt_list = 0; + tng_molecule_t mol; + tng_atom_t atom; + tng_bool found = TNG_FALSE; - (void) tng_data; - TNG_ASSERT(residue, "TNG library: residue must not be a NULL pointer."); - TNG_ASSERT(atom, "TNG library: atom must not be a NULL pointer."); + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); - if(index >= residue->n_atoms) + tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); + + if(!molecule_cnt_list) { - *atom = 0; return(TNG_FAILURE); } - chain = residue->chain; - molecule = chain->molecule; - if(index + residue->atoms_offset >= molecule->n_atoms) + for(i = 0; i < tng_data->n_molecules; i++) + { + mol = &tng_data->molecules[i]; + if(cnt + mol->n_atoms * molecule_cnt_list[i] - 1 < nr) + { + cnt += mol->n_atoms * molecule_cnt_list[i]; + continue; + } + atom = &mol->atoms[nr % mol->n_atoms]; + found = TNG_TRUE; + break; + } + if(!found) { - *atom = 0; return(TNG_FAILURE); } - *atom = &molecule->atoms[residue->atoms_offset + index]; + strncpy(name, atom->name, max_len - 1); + name[max_len - 1] = 0; + + if(strlen(atom->name) > (unsigned int)max_len - 1) + { + return(TNG_FAILURE); + } return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_residue_atom_add - (tng_trajectory_t tng_data, - tng_residue_t residue, - const char *atom_name, - const char *atom_type, - tng_atom_t *atom) +tng_function_status tng_atom_type_of_particle_nr_get + (const tng_trajectory_t tng_data, + const int64_t nr, + char *type, + const int max_len) { - int64_t id; + int64_t cnt = 0, i, *molecule_cnt_list = 0; + tng_molecule_t mol; + tng_atom_t atom; + tng_bool found = TNG_FALSE; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(atom_name, "TNG library: atom_name must not be a NULL pointer."); - TNG_ASSERT(atom_type, "TNG library: atom_type must not be a NULL pointer."); + TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); - /* Set ID to the ID of the last atom + 1 */ - if(residue->chain->molecule->n_atoms) + tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); + + if(!molecule_cnt_list) { - id = residue->chain->molecule->atoms[residue->chain->molecule->n_atoms-1].id + 1; + return(TNG_FAILURE); } - else + + for(i = 0; i < tng_data->n_molecules; i++) { - id = 0; + mol = &tng_data->molecules[i]; + if(cnt + mol->n_atoms * molecule_cnt_list[i] - 1 < nr) + { + cnt += mol->n_atoms * molecule_cnt_list[i]; + continue; + } + atom = &mol->atoms[nr % mol->n_atoms]; + found = TNG_TRUE; + break; + } + if(!found) + { + return(TNG_FAILURE); } - return(tng_residue_atom_w_id_add(tng_data, residue, atom_name, atom_type, - id, atom)); + strncpy(type, atom->atom_type, max_len - 1); + type[max_len - 1] = 0; + + if(strlen(atom->atom_type) > (unsigned int)max_len - 1) + { + return(TNG_FAILURE); + } + return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_residue_atom_w_id_add - (tng_trajectory_t tng_data, - tng_residue_t residue, - const char *atom_name, - const char *atom_type, - const int64_t id, - tng_atom_t *atom) +tng_function_status DECLSPECDLLEXPORT tng_particle_mapping_add + (const tng_trajectory_t tng_data, + const int64_t num_first_particle, + const int64_t n_particles, + const int64_t *mapping_table) { - tng_atom_t new_atoms; - tng_molecule_t molecule = residue->chain->molecule; - tng_function_status stat = TNG_SUCCESS; + int64_t i; + tng_particle_mapping_t mapping; + tng_trajectory_frame_set_t frame_set; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(atom_name, "TNG library: atom_name must not be a NULL pointer."); - TNG_ASSERT(atom_type, "TNG library: atom_type must not be a NULL pointer."); - if(!residue->n_atoms) + frame_set = &tng_data->current_trajectory_frame_set; + + /* Sanity check of the particle ranges. Split into multiple if + * statements for improved readability */ + for(i = 0; i < frame_set->n_mapping_blocks; i++) { - residue->atoms_offset = molecule->n_atoms; + mapping = &frame_set->mappings[i]; + if(num_first_particle >= mapping->num_first_particle && + num_first_particle < mapping->num_first_particle + + mapping->n_particles) + { + fprintf(stderr, "TNG library: Particle mapping overlap. %s: %d\n", __FILE__, __LINE__); + return(TNG_FAILURE); + } + if(num_first_particle + n_particles >= + mapping->num_first_particle && + num_first_particle + n_particles < + mapping->num_first_particle + mapping->n_particles) + { + fprintf(stderr, "TNG library: Particle mapping overlap. %s: %d\n", __FILE__, __LINE__); + return(TNG_FAILURE); + } + if(mapping->num_first_particle >= num_first_particle && + mapping->num_first_particle < num_first_particle + + n_particles) + { + fprintf(stderr, "TNG library: Particle mapping overlap. %s: %d\n", __FILE__, __LINE__); + return(TNG_FAILURE); + } + if(mapping->num_first_particle + mapping->n_particles > + num_first_particle && + mapping->num_first_particle + mapping->n_particles < + num_first_particle + n_particles) + { + fprintf(stderr, "TNG library: Particle mapping overlap. %s: %d\n", __FILE__, __LINE__); + return(TNG_FAILURE); + } } - new_atoms = realloc(molecule->atoms, - sizeof(struct tng_atom) * - (molecule->n_atoms + 1)); + frame_set->n_mapping_blocks++; - if(!new_atoms) + mapping = realloc(frame_set->mappings, sizeof(struct tng_particle_mapping) * + frame_set->n_mapping_blocks); + + if(!mapping) { fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(struct tng_atom) * (molecule->n_atoms + 1), + sizeof(struct tng_particle_mapping)*frame_set->n_mapping_blocks, __FILE__, __LINE__); - free(molecule->atoms); - molecule->atoms = 0; + free(frame_set->mappings); + frame_set->mappings = 0; return(TNG_CRITICAL); } + frame_set->mappings = mapping; - molecule->atoms = new_atoms; + frame_set->mappings[frame_set->n_mapping_blocks - 1].num_first_particle = num_first_particle; + frame_set->mappings[frame_set->n_mapping_blocks - 1].n_particles = n_particles; - *atom = &new_atoms[molecule->n_atoms]; - - tng_atom_init(*atom); - tng_atom_name_set(tng_data, *atom, atom_name); - tng_atom_type_set(tng_data, *atom, atom_type); - - (*atom)->residue = residue; - - residue->n_atoms++; - molecule->n_atoms++; - - (*atom)->id = id; - - return(stat); -} - -tng_function_status DECLSPECDLLEXPORT tng_molecule_alloc(const tng_trajectory_t tng_data, - tng_molecule_t *molecule_p) -{ - *molecule_p = malloc(sizeof(struct tng_molecule)); - if(!*molecule_p) + frame_set->mappings[frame_set->n_mapping_blocks - 1].real_particle_numbers = malloc(sizeof(int64_t) * n_particles); + if(!frame_set->mappings[frame_set->n_mapping_blocks - 1].real_particle_numbers) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n", - sizeof(struct tng_molecule), __FILE__, __LINE__); + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", + sizeof(int64_t) * n_particles, __FILE__, __LINE__); return(TNG_CRITICAL); } - tng_molecule_init(tng_data, *molecule_p); - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_molecule_free(const tng_trajectory_t tng_data, - tng_molecule_t *molecule_p) -{ - if(!*molecule_p) + for(i=0; imappings[frame_set->n_mapping_blocks - 1].real_particle_numbers[i] = mapping_table[i]; } - tng_molecule_destroy(tng_data, *molecule_p); - - free(*molecule_p); - *molecule_p = 0; - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_molecule_init(const tng_trajectory_t tng_data, - tng_molecule_t molecule) -{ - (void)tng_data; - molecule->quaternary_str = 1; - molecule->name = 0; - molecule->n_chains = 0; - molecule->chains = 0; - molecule->n_residues = 0; - molecule->residues = 0; - molecule->n_atoms = 0; - molecule->atoms = 0; - molecule->n_bonds = 0; - molecule->bonds = 0; - return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_destroy(const tng_trajectory_t tng_data, - tng_molecule_t molecule) +tng_function_status DECLSPECDLLEXPORT tng_frame_set_particle_mapping_free(const tng_trajectory_t tng_data) { + tng_trajectory_frame_set_t frame_set; + tng_particle_mapping_t mapping; int64_t i; - (void)tng_data; - if(molecule->name) - { - free(molecule->name); - molecule->name = 0; - } + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - if(molecule->chains) - { - for(i = 0; i < molecule->n_chains; i++) - { - if(molecule->chains[i].name) - { - free(molecule->chains[i].name); - molecule->chains[i].name = 0; - } - } - free(molecule->chains); - molecule->chains = 0; - } - molecule->n_chains = 0; + frame_set = &tng_data->current_trajectory_frame_set; - if(molecule->residues) + if(frame_set->n_mapping_blocks && frame_set->mappings) { - for(i = 0; i < molecule->n_residues; i++) + for(i = 0; i < frame_set->n_mapping_blocks; i++) { - if(molecule->residues[i].name) + mapping = &frame_set->mappings[i]; + if(mapping->real_particle_numbers) { - free(molecule->residues[i].name); - molecule->residues[i].name = 0; + free(mapping->real_particle_numbers); + mapping->real_particle_numbers = 0; } } - free(molecule->residues); - molecule->residues = 0; - } - molecule->n_residues = 0; - - if(molecule->atoms) - { - for(i = 0; i < molecule->n_atoms; i++) - { - tng_atom_destroy(&molecule->atoms[i]); - } - free(molecule->atoms); - molecule->atoms = 0; - } - molecule->n_atoms = 0; - - if(molecule->bonds) - { - free(molecule->bonds); - molecule->bonds = 0; + free(frame_set->mappings); + frame_set->mappings = 0; + frame_set->n_mapping_blocks = 0; } - molecule->n_bonds = 0; return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_molecule_name_of_particle_nr_get - (const tng_trajectory_t tng_data, - const int64_t nr, - char *name, - int max_len) +tng_function_status DECLSPECDLLEXPORT tng_trajectory_init(tng_trajectory_t *tng_data_p) { - int64_t cnt = 0, i, *molecule_cnt_list = 0; - tng_molecule_t mol; - tng_bool found = TNG_FALSE; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); - - tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); - - if(!molecule_cnt_list) - { - return(TNG_FAILURE); - } - - for(i = 0; i < tng_data->n_molecules; i++) - { - mol = &tng_data->molecules[i]; - if(cnt + mol->n_atoms * molecule_cnt_list[i] - 1 < nr) - { - cnt += mol->n_atoms * molecule_cnt_list[i]; - continue; - } - found = TNG_TRUE; - break; - } - if(!found) - { - return(TNG_FAILURE); - } - - strncpy(name, mol->name, max_len - 1); - name[max_len - 1] = 0; + time_t seconds; + tng_trajectory_frame_set_t frame_set; + tng_trajectory_t tng_data; - if(strlen(mol->name) > (unsigned int)max_len - 1) + *tng_data_p = malloc(sizeof(struct tng_trajectory)); + if(!*tng_data_p) { - return(TNG_FAILURE); + fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n", + sizeof(struct tng_trajectory), __FILE__, __LINE__); + return(TNG_CRITICAL); } - return(TNG_SUCCESS); -} -tng_function_status DECLSPECDLLEXPORT tng_molecule_id_of_particle_nr_get - (const tng_trajectory_t tng_data, - const int64_t nr, - int64_t *id) -{ - int64_t cnt = 0, i, *molecule_cnt_list = 0; - tng_molecule_t mol; - tng_bool found = TNG_FALSE; + tng_data = *tng_data_p; - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(id, "TNG library: id must not be a NULL pointer."); + frame_set = &tng_data->current_trajectory_frame_set; - tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); + tng_data->input_file_path = 0; + tng_data->input_file = 0; + tng_data->input_file_len = 0; + tng_data->output_file_path = 0; + tng_data->output_file = 0; - if(!molecule_cnt_list) - { - return(TNG_FAILURE); - } + tng_data->first_program_name = 0; + tng_data->first_user_name = 0; + tng_data->first_computer_name = 0; + tng_data->first_pgp_signature = 0; + tng_data->last_program_name = 0; + tng_data->last_user_name = 0; + tng_data->last_computer_name = 0; + tng_data->last_pgp_signature = 0; + tng_data->forcefield_name = 0; - for(i = 0; i < tng_data->n_molecules; i++) + seconds = time(0); + if ( seconds == -1) { - mol = &tng_data->molecules[i]; - if(cnt + mol->n_atoms * molecule_cnt_list[i] - 1 < nr) - { - cnt += mol->n_atoms * molecule_cnt_list[i]; - continue; - } - found = TNG_TRUE; - break; + fprintf(stderr, "TNG library: Cannot get time. %s: %d\n", __FILE__, __LINE__); } - if(!found) + else { - return(TNG_FAILURE); + tng_data->time = seconds; } - *id = mol->id; + tng_data->var_num_atoms_flag = TNG_CONSTANT_N_ATOMS; + tng_data->first_trajectory_frame_set_input_file_pos = -1; + tng_data->last_trajectory_frame_set_input_file_pos = -1; + tng_data->current_trajectory_frame_set_input_file_pos = -1; + tng_data->first_trajectory_frame_set_output_file_pos = -1; + tng_data->last_trajectory_frame_set_output_file_pos = -1; + tng_data->current_trajectory_frame_set_output_file_pos = -1; + tng_data->frame_set_n_frames = 100; + tng_data->n_trajectory_frame_sets = 0; + tng_data->medium_stride_length = 100; + tng_data->long_stride_length = 10000; - return(TNG_SUCCESS); -} + tng_data->time_per_frame = -1; -tng_function_status DECLSPECDLLEXPORT tng_molsystem_bonds_get - (const tng_trajectory_t tng_data, - int64_t *n_bonds, - int64_t **from_atoms, - int64_t **to_atoms) -{ - int64_t atom_cnt = 0, cnt, mol_cnt, i, j, k; - int64_t from_atom, to_atom, *molecule_cnt_list = 0; - tng_molecule_t mol; - tng_bond_t bond; + tng_data->n_particle_data_blocks = 0; + tng_data->n_data_blocks = 0; - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(n_bonds, "TNG library: n_bonds must not be a NULL pointer."); - TNG_ASSERT(from_atoms, "TNG library: from_atoms must not be a NULL pointer."); - TNG_ASSERT(to_atoms, "TNG library: to_atoms must not be a NULL pointer."); + tng_data->non_tr_particle_data = 0; + tng_data->non_tr_data = 0; - tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); + tng_data->compress_algo_pos = 0; + tng_data->compress_algo_vel = 0; + tng_data->compression_precision = 1000; + tng_data->distance_unit_exponential = -9; - if(!molecule_cnt_list) - { - return(TNG_FAILURE); - } + frame_set->first_frame = -1; + frame_set->n_mapping_blocks = 0; + frame_set->mappings = 0; + frame_set->molecule_cnt_list = 0; - *n_bonds = 0; - /* First count the total number of bonds to allocate memory */ - for(i = 0; i < tng_data->n_molecules; i++) - { - mol = &tng_data->molecules[i]; - mol_cnt = molecule_cnt_list[i]; - *n_bonds += mol_cnt * mol->n_bonds; - } - if(*n_bonds == 0) - { - return(TNG_SUCCESS); - } + frame_set->n_particle_data_blocks = 0; + frame_set->n_data_blocks = 0; + + frame_set->tr_particle_data = 0; + frame_set->tr_data = 0; + + frame_set->n_written_frames = 0; + frame_set->n_unwritten_frames = 0; + + frame_set->next_frame_set_file_pos = -1; + frame_set->prev_frame_set_file_pos = -1; + frame_set->medium_stride_next_frame_set_file_pos = -1; + frame_set->medium_stride_prev_frame_set_file_pos = -1; + frame_set->long_stride_next_frame_set_file_pos = -1; + frame_set->long_stride_prev_frame_set_file_pos = -1; + + frame_set->first_frame_time = -1; + + tng_data->n_molecules = 0; + tng_data->molecules = 0; + tng_data->molecule_cnt_list = 0; + tng_data->n_particles = 0; - *from_atoms = malloc(sizeof(int64_t) * (*n_bonds)); - if(!*from_atoms) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(int64_t) * (*n_bonds), __FILE__, __LINE__); - return(TNG_CRITICAL); + /* Check the endianness of the computer */ + static int32_t endianness_32 = 0x01234567; + /* 0x01234567 */ + if ( *(const unsigned char*)&endianness_32 == 0x01 ) + { + tng_data->endianness_32 = TNG_BIG_ENDIAN_32; + } + + /* 0x67452301 */ + else if( *(const unsigned char*)&endianness_32 == 0x67 ) + { + tng_data->endianness_32 = TNG_LITTLE_ENDIAN_32; + + } + + /* 0x45670123 */ + else if ( *(const unsigned char*)&endianness_32 == 0x45 ) + { + tng_data->endianness_32 = TNG_BYTE_PAIR_SWAP_32; + } } - *to_atoms = malloc(sizeof(int64_t) * (*n_bonds)); - if(!*to_atoms) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(int64_t) * (*n_bonds), __FILE__, __LINE__); - free(*from_atoms); - *from_atoms = 0; - return(TNG_CRITICAL); - } + static int64_t endianness_64 = 0x0123456789ABCDEFLL; + /* 0x0123456789ABCDEF */ + if ( *(const unsigned char*)&endianness_64 == 0x01 ) + { + tng_data->endianness_64 = TNG_BIG_ENDIAN_64; + } - cnt = 0; - for(i = 0; i < tng_data->n_molecules; i++) - { - mol = &tng_data->molecules[i]; - mol_cnt = molecule_cnt_list[i]; - for(j = 0; j < mol_cnt; j++) + /* 0xEFCDAB8967452301 */ + else if ( *(const unsigned char*)&endianness_64 == 0xEF ) { - for(k = 0; k < mol->n_bonds; k++) - { - bond = &mol->bonds[k]; - from_atom = atom_cnt + bond->from_atom_id; - to_atom = atom_cnt + bond->to_atom_id; - (*from_atoms)[cnt] = from_atom; - (*to_atoms)[cnt++] = to_atom; - } - atom_cnt += mol->n_atoms; + tng_data->endianness_64 = TNG_LITTLE_ENDIAN_64; + } + + /* 0x89ABCDEF01234567 */ + else if ( *(const unsigned char*)&endianness_64 == 0x89 ) + { + tng_data->endianness_64 = TNG_QUAD_SWAP_64; + } + + /* 0x45670123CDEF89AB */ + else if ( *(const unsigned char*)&endianness_64 == 0x45 ) + { + tng_data->endianness_64 = TNG_BYTE_PAIR_SWAP_64; + } + + /* 0x23016745AB89EFCD */ + else if ( *(const unsigned char*)&endianness_64 == 0x23 ) + { + tng_data->endianness_64 = TNG_BYTE_SWAP_64; } } + /* By default do not swap the byte order, i.e. keep the byte order of the + * architecture. The input file endianness will be set when reading the + * header. The output endianness can be changed - before the file is + * written. */ + tng_data->input_endianness_swap_func_32 = 0; + tng_data->input_endianness_swap_func_64 = 0; + tng_data->output_endianness_swap_func_32 = 0; + tng_data->output_endianness_swap_func_64 = 0; + + tng_data->current_trajectory_frame_set.next_frame_set_file_pos = -1; + tng_data->current_trajectory_frame_set.prev_frame_set_file_pos = -1; + tng_data->current_trajectory_frame_set.n_frames = 0; + return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_chain_name_of_particle_nr_get - (const tng_trajectory_t tng_data, - const int64_t nr, - char *name, - int max_len) +tng_function_status DECLSPECDLLEXPORT tng_trajectory_destroy(tng_trajectory_t *tng_data_p) { - int64_t cnt = 0, i, *molecule_cnt_list = 0; - tng_molecule_t mol; - tng_atom_t atom; - tng_bool found = TNG_FALSE; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); - - tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); + int64_t i, j, k, l; + int64_t n_particles, n_values_per_frame; + tng_trajectory_t tng_data = *tng_data_p; + tng_trajectory_frame_set_t frame_set; - if(!molecule_cnt_list) + if(!*tng_data_p) { - return(TNG_FAILURE); + return(TNG_SUCCESS); } - for(i = 0; i < tng_data->n_molecules; i++) + frame_set = &tng_data->current_trajectory_frame_set; + + if(tng_data->input_file) { - mol = &tng_data->molecules[i]; - if(cnt + mol->n_atoms * molecule_cnt_list[i] - 1 < nr) + if(tng_data->output_file == tng_data->input_file) { - cnt += mol->n_atoms * molecule_cnt_list[i]; - continue; + tng_frame_set_finalize(tng_data, TNG_USE_HASH); + tng_data->output_file = 0; } - atom = &mol->atoms[nr % mol->n_atoms]; - found = TNG_TRUE; - break; + fclose(tng_data->input_file); + tng_data->input_file = 0; } - if(!found) + + if(tng_data->input_file_path) { - return(TNG_FAILURE); + free(tng_data->input_file_path); + tng_data->input_file_path = 0; } - if(!atom->residue || !atom->residue->chain) + + if(tng_data->output_file) { - return(TNG_FAILURE); + /* FIXME: Do not always write the hash */ + tng_frame_set_finalize(tng_data, TNG_USE_HASH); + fclose(tng_data->output_file); + tng_data->output_file = 0; } - strncpy(name, atom->residue->chain->name, max_len - 1); - name[max_len - 1] = 0; - - if(strlen(atom->residue->chain->name) > (unsigned int)max_len - 1) + if(tng_data->output_file_path) { - return(TNG_FAILURE); + free(tng_data->output_file_path); + tng_data->output_file_path = 0; } - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_residue_name_of_particle_nr_get - (const tng_trajectory_t tng_data, - const int64_t nr, - char *name, - int max_len) -{ - int64_t cnt = 0, i, *molecule_cnt_list = 0; - tng_molecule_t mol; - tng_atom_t atom; - tng_bool found = TNG_FALSE; - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); + if(tng_data->first_program_name) + { + free(tng_data->first_program_name); + tng_data->first_program_name = 0; + } - tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); + if(tng_data->last_program_name) + { + free(tng_data->last_program_name); + tng_data->last_program_name = 0; + } - if(!molecule_cnt_list) + if(tng_data->first_user_name) { - return(TNG_FAILURE); + free(tng_data->first_user_name); + tng_data->first_user_name = 0; } - for(i = 0; i < tng_data->n_molecules; i++) + if(tng_data->last_user_name) { - mol = &tng_data->molecules[i]; - if(cnt + mol->n_atoms * molecule_cnt_list[i] - 1 < nr) - { - cnt += mol->n_atoms * molecule_cnt_list[i]; - continue; - } - atom = &mol->atoms[nr % mol->n_atoms]; - found = TNG_TRUE; - break; + free(tng_data->last_user_name); + tng_data->last_user_name = 0; } - if(!found) + + if(tng_data->first_computer_name) { - return(TNG_FAILURE); + free(tng_data->first_computer_name); + tng_data->first_computer_name = 0; } - if(!atom->residue) + + if(tng_data->last_computer_name) { - return(TNG_FAILURE); + free(tng_data->last_computer_name); + tng_data->last_computer_name = 0; } - strncpy(name, atom->residue->name, max_len - 1); - name[max_len - 1] = 0; + if(tng_data->first_pgp_signature) + { + free(tng_data->first_pgp_signature); + tng_data->first_pgp_signature = 0; + } - if(strlen(atom->residue->name) > (unsigned int)max_len - 1) + if(tng_data->last_pgp_signature) { - return(TNG_FAILURE); + free(tng_data->last_pgp_signature); + tng_data->last_pgp_signature = 0; } - return(TNG_SUCCESS); -} -tng_function_status DECLSPECDLLEXPORT tng_residue_id_of_particle_nr_get - (const tng_trajectory_t tng_data, - const int64_t nr, - int64_t *id) -{ - int64_t cnt = 0, i, *molecule_cnt_list = 0; - tng_molecule_t mol; - tng_atom_t atom; - tng_bool found = TNG_FALSE; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(id, "TNG library: id must not be a NULL pointer."); - - tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); - - if(!molecule_cnt_list) - { - return(TNG_FAILURE); - } - - for(i = 0; i < tng_data->n_molecules; i++) - { - mol = &tng_data->molecules[i]; - if(cnt + mol->n_atoms * molecule_cnt_list[i] - 1 < nr) - { - cnt += mol->n_atoms * molecule_cnt_list[i]; - continue; - } - atom = &mol->atoms[nr % mol->n_atoms]; - found = TNG_TRUE; - break; - } - if(!found) - { - return(TNG_FAILURE); - } - if(!atom->residue) + if(tng_data->forcefield_name) { - return(TNG_FAILURE); + free(tng_data->forcefield_name); + tng_data->forcefield_name = 0; } - *id = atom->residue->id; - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_global_residue_id_of_particle_nr_get - (const tng_trajectory_t tng_data, - const int64_t nr, - int64_t *id) -{ - int64_t cnt = 0, i, offset = 0, *molecule_cnt_list = 0; - tng_molecule_t mol; - tng_atom_t atom; - tng_bool found = TNG_FALSE; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(id, "TNG library: id must not be a NULL pointer."); - - tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); + tng_frame_set_particle_mapping_free(tng_data); - if(!molecule_cnt_list) + if(frame_set->molecule_cnt_list) { - return(TNG_FAILURE); + free(frame_set->molecule_cnt_list); + frame_set->molecule_cnt_list = 0; } - for(i = 0; i < tng_data->n_molecules; i++) - { - mol = &tng_data->molecules[i]; - if(cnt + mol->n_atoms * molecule_cnt_list[i] - 1 < nr) - { - cnt += mol->n_atoms * molecule_cnt_list[i]; - offset += mol->n_residues * molecule_cnt_list[i]; - continue; - } - atom = &mol->atoms[nr % mol->n_atoms]; - found = TNG_TRUE; - break; - } - if(!found) + if(tng_data->var_num_atoms_flag) { - return(TNG_FAILURE); + n_particles = frame_set->n_particles; } - if(!atom->residue) + else { - return(TNG_FAILURE); + n_particles = tng_data->n_particles; } - offset += mol->n_residues * ((nr - cnt) / mol->n_atoms); - - *id = atom->residue->id + offset; - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_atom_name_of_particle_nr_get - (const tng_trajectory_t tng_data, - const int64_t nr, - char *name, - int max_len) -{ - int64_t cnt = 0, i, *molecule_cnt_list = 0; - tng_molecule_t mol; - tng_atom_t atom; - tng_bool found = TNG_FALSE; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); + if(tng_data->non_tr_particle_data) + { + for(i = 0; i < tng_data->n_particle_data_blocks; i++) + { + if(tng_data->non_tr_particle_data[i].values) + { + free(tng_data->non_tr_particle_data[i].values); + tng_data->non_tr_particle_data[i].values = 0; + } - tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); + if(tng_data->non_tr_particle_data[i].strings) + { + n_values_per_frame = tng_data->non_tr_particle_data[i]. + n_values_per_frame; + if(tng_data->non_tr_particle_data[i].strings[0]) + { + for(j = 0; j < n_particles; j++) + { + if(tng_data->non_tr_particle_data[i].strings[0][j]) + { + for(k = 0; k < n_values_per_frame; k++) + { + if(tng_data->non_tr_particle_data[i]. + strings[0][j][k]) + { + free(tng_data->non_tr_particle_data[i]. + strings[0][j][k]); + tng_data->non_tr_particle_data[i]. + strings[0][j][k] = 0; + } + } + free(tng_data->non_tr_particle_data[i]. + strings[0][j]); + tng_data->non_tr_particle_data[i].strings[0][j] = 0; + } + } + free(tng_data->non_tr_particle_data[i].strings[0]); + tng_data->non_tr_particle_data[i].strings[0] = 0; + } + free(tng_data->non_tr_particle_data[i].strings); + tng_data->non_tr_particle_data[i].strings = 0; + } - if(!molecule_cnt_list) - { - return(TNG_FAILURE); + if(tng_data->non_tr_particle_data[i].block_name) + { + free(tng_data->non_tr_particle_data[i].block_name); + tng_data->non_tr_particle_data[i].block_name = 0; + } + } + free(tng_data->non_tr_particle_data); + tng_data->non_tr_particle_data = 0; } - for(i = 0; i < tng_data->n_molecules; i++) + if(tng_data->non_tr_data) { - mol = &tng_data->molecules[i]; - if(cnt + mol->n_atoms * molecule_cnt_list[i] - 1 < nr) + for(i = 0; i < tng_data->n_data_blocks; i++) { - cnt += mol->n_atoms * molecule_cnt_list[i]; - continue; + if(tng_data->non_tr_data[i].values) + { + free(tng_data->non_tr_data[i].values); + tng_data->non_tr_data[i].values = 0; + } + + if(tng_data->non_tr_data[i].strings) + { + n_values_per_frame = tng_data->non_tr_data[i]. + n_values_per_frame; + if(tng_data->non_tr_data[i].strings[0][0]) + { + for(j = 0; j < n_values_per_frame; j++) + { + if(tng_data->non_tr_data[i].strings[0][0][j]) + { + free(tng_data->non_tr_data[i].strings[0][0][j]); + tng_data->non_tr_data[i].strings[0][0][j] = 0; + } + } + free(tng_data->non_tr_data[i].strings[0][0]); + tng_data->non_tr_data[i].strings[0][0] = 0; + } + free(tng_data->non_tr_data[i].strings[0]); + tng_data->non_tr_data[i].strings[0] = 0; + free(tng_data->non_tr_data[i].strings); + tng_data->non_tr_data[i].strings = 0; + } + + if(tng_data->non_tr_data[i].block_name) + { + free(tng_data->non_tr_data[i].block_name); + tng_data->non_tr_data[i].block_name = 0; + } } - atom = &mol->atoms[nr % mol->n_atoms]; - found = TNG_TRUE; - break; - } - if(!found) - { - return(TNG_FAILURE); + free(tng_data->non_tr_data); + tng_data->non_tr_data = 0; } - strncpy(name, atom->name, max_len - 1); - name[max_len - 1] = 0; + tng_data->n_particle_data_blocks = 0; + tng_data->n_data_blocks = 0; - if(strlen(atom->name) > (unsigned int)max_len - 1) + if(tng_data->compress_algo_pos) { - return(TNG_FAILURE); + free(tng_data->compress_algo_pos); + tng_data->compress_algo_pos = 0; } - return(TNG_SUCCESS); -} - -tng_function_status tng_atom_type_of_particle_nr_get - (const tng_trajectory_t tng_data, - const int64_t nr, - char *type, - int max_len) -{ - int64_t cnt = 0, i, *molecule_cnt_list = 0; - tng_molecule_t mol; - tng_atom_t atom; - tng_bool found = TNG_FALSE; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); - - tng_molecule_cnt_list_get(tng_data, &molecule_cnt_list); - - if(!molecule_cnt_list) + if(tng_data->compress_algo_vel) { - return(TNG_FAILURE); + free(tng_data->compress_algo_vel); + tng_data->compress_algo_vel = 0; } - for(i = 0; i < tng_data->n_molecules; i++) + if(frame_set->tr_particle_data) { - mol = &tng_data->molecules[i]; - if(cnt + mol->n_atoms * molecule_cnt_list[i] - 1 < nr) + for(i = 0; i < frame_set->n_particle_data_blocks; i++) { - cnt += mol->n_atoms * molecule_cnt_list[i]; - continue; - } - atom = &mol->atoms[nr % mol->n_atoms]; - found = TNG_TRUE; - break; - } - if(!found) - { - return(TNG_FAILURE); - } + if(frame_set->tr_particle_data[i].values) + { + free(frame_set->tr_particle_data[i].values); + frame_set->tr_particle_data[i].values = 0; + } - strncpy(type, atom->atom_type, max_len - 1); - type[max_len - 1] = 0; + if(frame_set->tr_particle_data[i].strings) + { + n_values_per_frame = frame_set->tr_particle_data[i]. + n_values_per_frame; + for(j = 0; j < frame_set->tr_particle_data[i].n_frames; j++) + { + if(frame_set->tr_particle_data[i].strings[j]) + { + for(k = 0; k < n_particles; k++) + { + if(frame_set->tr_particle_data[i]. + strings[j][k]) + { + for(l = 0; l < n_values_per_frame; l++) + { + if(frame_set->tr_particle_data[i]. + strings[j][k][l]) + { + free(frame_set->tr_particle_data[i]. + strings[j][k][l]); + frame_set->tr_particle_data[i]. + strings[j][k][l] = 0; + } + } + free(frame_set->tr_particle_data[i]. + strings[j][k]); + frame_set->tr_particle_data[i]. + strings[j][k] = 0; + } + } + free(frame_set->tr_particle_data[i].strings[j]); + frame_set->tr_particle_data[i].strings[j] = 0; + } + } + free(frame_set->tr_particle_data[i].strings); + frame_set->tr_particle_data[i].strings = 0; + } - if(strlen(atom->atom_type) > (unsigned int)max_len - 1) - { - return(TNG_FAILURE); + if(frame_set->tr_particle_data[i].block_name) + { + free(frame_set->tr_particle_data[i].block_name); + frame_set->tr_particle_data[i].block_name = 0; + } + } + free(frame_set->tr_particle_data); + frame_set->tr_particle_data = 0; } - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_particle_mapping_add - (tng_trajectory_t tng_data, - const int64_t num_first_particle, - const int64_t n_particles, - const int64_t *mapping_table) -{ - int64_t i; - tng_particle_mapping_t mapping; - 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; - /* Sanity check of the particle ranges. Split into multiple if - * statements for improved readability */ - for(i = 0; i < frame_set->n_mapping_blocks; i++) + if(frame_set->tr_data) { - mapping = &frame_set->mappings[i]; - if(num_first_particle >= mapping->num_first_particle && - num_first_particle < mapping->num_first_particle + - mapping->n_particles) - { - fprintf(stderr, "TNG library: Particle mapping overlap. %s: %d\n", __FILE__, __LINE__); - return(TNG_FAILURE); - } - if(num_first_particle + n_particles >= - mapping->num_first_particle && - num_first_particle + n_particles < - mapping->num_first_particle + mapping->n_particles) - { - fprintf(stderr, "TNG library: Particle mapping overlap. %s: %d\n", __FILE__, __LINE__); - return(TNG_FAILURE); - } - if(mapping->num_first_particle >= num_first_particle && - mapping->num_first_particle < num_first_particle + - n_particles) - { - fprintf(stderr, "TNG library: Particle mapping overlap. %s: %d\n", __FILE__, __LINE__); - return(TNG_FAILURE); - } - if(mapping->num_first_particle + mapping->n_particles > - num_first_particle && - mapping->num_first_particle + mapping->n_particles < - num_first_particle + n_particles) + for(i = 0; i < frame_set->n_data_blocks; i++) { - fprintf(stderr, "TNG library: Particle mapping overlap. %s: %d\n", __FILE__, __LINE__); - return(TNG_FAILURE); - } - } - - frame_set->n_mapping_blocks++; + if(frame_set->tr_data[i].values) + { + free(frame_set->tr_data[i].values); + frame_set->tr_data[i].values = 0; + } - mapping = realloc(frame_set->mappings, sizeof(struct tng_particle_mapping) * - frame_set->n_mapping_blocks); + if(frame_set->tr_data[i].strings) + { + n_values_per_frame = frame_set->tr_data[i]. + n_values_per_frame; + for(j = 0; j < frame_set->tr_data[i].n_frames; j++) + { + if(frame_set->tr_data[i].strings[j]) + { + for(k = 0; k < n_values_per_frame; k++) + { + if(frame_set->tr_data[i].strings[j][k]) + { + free(frame_set->tr_data[i].strings[j][k]); + frame_set->tr_data[i].strings[j][k] = 0; + } + } + free(frame_set->tr_data[i].strings[j]); + frame_set->tr_data[i].strings[j] = 0; + } + } + free(frame_set->tr_data[i].strings); + frame_set->tr_data[i].strings = 0; + } - if(!mapping) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(struct tng_particle_mapping)*frame_set->n_mapping_blocks, - __FILE__, __LINE__); - free(frame_set->mappings); - frame_set->mappings = 0; - return(TNG_CRITICAL); + if(frame_set->tr_data[i].block_name) + { + free(frame_set->tr_data[i].block_name); + frame_set->tr_data[i].block_name = 0; + } + } + free(frame_set->tr_data); + frame_set->tr_data = 0; } - frame_set->mappings = mapping; - frame_set->mappings[frame_set->n_mapping_blocks - 1].num_first_particle = num_first_particle; - frame_set->mappings[frame_set->n_mapping_blocks - 1].n_particles = n_particles; + frame_set->n_particle_data_blocks = 0; + frame_set->n_data_blocks = 0; - frame_set->mappings[frame_set->n_mapping_blocks - 1].real_particle_numbers = malloc(sizeof(int64_t) * n_particles); - if(!frame_set->mappings[frame_set->n_mapping_blocks - 1].real_particle_numbers) + if(tng_data->molecules) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(int64_t) * n_particles, __FILE__, __LINE__); - return(TNG_CRITICAL); + for(i = 0; i < tng_data->n_molecules; i++) + { + tng_molecule_destroy(tng_data, &tng_data->molecules[i]); + } + free(tng_data->molecules); + tng_data->molecules = 0; + tng_data->n_molecules = 0; } - - for(i=0; imolecule_cnt_list) { - frame_set->mappings[frame_set->n_mapping_blocks - 1].real_particle_numbers[i] = mapping_table[i]; + free(tng_data->molecule_cnt_list); + tng_data->molecule_cnt_list = 0; } - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_frame_set_particle_mapping_free(tng_trajectory_t tng_data) -{ - tng_trajectory_frame_set_t frame_set; - tng_particle_mapping_t mapping; - int64_t i; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - - frame_set = &tng_data->current_trajectory_frame_set; - - if(frame_set->n_mapping_blocks && frame_set->mappings) - { - for(i = 0; i < frame_set->n_mapping_blocks; i++) - { - mapping = &frame_set->mappings[i]; - if(mapping->real_particle_numbers) - { - free(mapping->real_particle_numbers); - mapping->real_particle_numbers = 0; - } - } - free(frame_set->mappings); - frame_set->mappings = 0; - frame_set->n_mapping_blocks = 0; - } + free(*tng_data_p); + *tng_data_p = 0; return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_trajectory_init(tng_trajectory_t *tng_data_p) +tng_function_status DECLSPECDLLEXPORT tng_trajectory_init_from_src + (const tng_trajectory_t src, + tng_trajectory_t *dest_p) { - time_t seconds; tng_trajectory_frame_set_t frame_set; - tng_trajectory_t tng_data; + tng_trajectory_t dest; - *tng_data_p = malloc(sizeof(struct tng_trajectory)); - if(!*tng_data_p) + TNG_ASSERT(src != 0, "TNG library: Source trajectory must not be NULL."); + + *dest_p = malloc(sizeof(struct tng_trajectory)); + if(!*dest_p) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n", + fprintf(stderr, "TNG library: Cannot allocate memory (%lu bytes). %s: %d\n", sizeof(struct tng_trajectory), __FILE__, __LINE__); return(TNG_CRITICAL); } - tng_data = *tng_data_p; - - frame_set = &tng_data->current_trajectory_frame_set; - - tng_data->input_file_path = 0; - tng_data->input_file = 0; - tng_data->input_file_len = 0; - tng_data->output_file_path = 0; - tng_data->output_file = 0; + dest = *dest_p; - tng_data->first_program_name = 0; - tng_data->first_user_name = 0; - tng_data->first_computer_name = 0; - tng_data->first_pgp_signature = 0; - tng_data->last_program_name = 0; - tng_data->last_user_name = 0; - tng_data->last_computer_name = 0; - tng_data->last_pgp_signature = 0; - tng_data->forcefield_name = 0; + frame_set = &dest->current_trajectory_frame_set; - seconds = time(0); - if ( seconds == -1) + if(src->input_file_path) { - fprintf(stderr, "TNG library: Cannot get time. %s: %d\n", __FILE__, __LINE__); + dest->input_file_path = malloc(strlen(src->input_file_path) + 1); + if(!dest->input_file_path) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", + (unsigned int)strlen(src->input_file_path) + 1, __FILE__, __LINE__); + return(TNG_CRITICAL); + } + strcpy(dest->input_file_path, src->input_file_path); + dest->input_file_len = src->input_file_len; } else { - tng_data->time = seconds; + dest->input_file_path = 0; + } + dest->input_file = 0; + if(src->output_file_path) + { + dest->output_file_path = malloc(strlen(src->output_file_path) + 1); + if(!dest->output_file_path) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", + (unsigned int)strlen(src->output_file_path) + 1, __FILE__, __LINE__); + return(TNG_CRITICAL); + } + strcpy(dest->output_file_path, src->output_file_path); + } + else + { + dest->output_file_path = 0; } + dest->output_file = 0; - tng_data->var_num_atoms_flag = TNG_CONSTANT_N_ATOMS; - tng_data->first_trajectory_frame_set_input_file_pos = -1; - tng_data->last_trajectory_frame_set_input_file_pos = -1; - tng_data->current_trajectory_frame_set_input_file_pos = -1; - tng_data->first_trajectory_frame_set_output_file_pos = -1; - tng_data->last_trajectory_frame_set_output_file_pos = -1; - tng_data->current_trajectory_frame_set_output_file_pos = -1; - tng_data->frame_set_n_frames = 100; - tng_data->n_trajectory_frame_sets = 0; - tng_data->medium_stride_length = 100; - tng_data->long_stride_length = 10000; + dest->first_program_name = 0; + dest->first_user_name = 0; + dest->first_computer_name = 0; + dest->first_pgp_signature = 0; + dest->last_program_name = 0; + dest->last_user_name = 0; + dest->last_computer_name = 0; + dest->last_pgp_signature = 0; + dest->forcefield_name = 0; - tng_data->time_per_frame = -1; + dest->var_num_atoms_flag = src->var_num_atoms_flag; + dest->first_trajectory_frame_set_input_file_pos = + src->first_trajectory_frame_set_input_file_pos; + dest->last_trajectory_frame_set_input_file_pos = + src->last_trajectory_frame_set_input_file_pos; + dest->current_trajectory_frame_set_input_file_pos = + src->current_trajectory_frame_set_input_file_pos; + dest->first_trajectory_frame_set_output_file_pos = + src->first_trajectory_frame_set_output_file_pos; + dest->last_trajectory_frame_set_output_file_pos = + src->last_trajectory_frame_set_output_file_pos; + dest->current_trajectory_frame_set_output_file_pos = + src->current_trajectory_frame_set_output_file_pos; + dest->frame_set_n_frames = src->frame_set_n_frames; + dest->n_trajectory_frame_sets = src->n_trajectory_frame_sets; + dest->medium_stride_length = src->medium_stride_length; + dest->long_stride_length = src->long_stride_length; - tng_data->n_particle_data_blocks = 0; - tng_data->n_data_blocks = 0; + dest->time_per_frame = src->time_per_frame; - tng_data->non_tr_particle_data = 0; - tng_data->non_tr_data = 0; + /* Currently the non trajectory data blocks are not copied since it + * can lead to problems when freeing memory in a parallel block. */ + dest->n_particle_data_blocks = 0; + dest->n_data_blocks = 0; + dest->non_tr_particle_data = 0; + dest->non_tr_data = 0; - tng_data->compress_algo_pos = 0; - tng_data->compress_algo_vel = 0; - tng_data->compression_precision = 1000; - tng_data->distance_unit_exponential = -9; + dest->compress_algo_pos = 0; + dest->compress_algo_vel = 0; + dest->distance_unit_exponential = -9; + dest->compression_precision = 1000; - frame_set->first_frame = -1; frame_set->n_mapping_blocks = 0; frame_set->mappings = 0; frame_set->molecule_cnt_list = 0; @@ -9878,885 +9338,619 @@ tng_function_status DECLSPECDLLEXPORT tng_trajectory_init(tng_trajectory_t *tng_ frame_set->medium_stride_prev_frame_set_file_pos = -1; frame_set->long_stride_next_frame_set_file_pos = -1; frame_set->long_stride_prev_frame_set_file_pos = -1; + frame_set->first_frame = -1; - frame_set->first_frame_time = -1; - - tng_data->n_molecules = 0; - tng_data->molecules = 0; - tng_data->molecule_cnt_list = 0; - tng_data->n_particles = 0; - - { - /* Check the endianness of the computer */ - static int32_t endianness_32 = 0x01234567; - /* 0x01234567 */ - if ( *(const unsigned char*)&endianness_32 == 0x01 ) - { - tng_data->endianness_32 = TNG_BIG_ENDIAN_32; - } - - /* 0x67452301 */ - else if( *(const unsigned char*)&endianness_32 == 0x67 ) - { - tng_data->endianness_32 = TNG_LITTLE_ENDIAN_32; + dest->n_molecules = 0; + dest->molecules = 0; + dest->molecule_cnt_list = 0; + dest->n_particles = src->n_particles; - } + dest->endianness_32 = src->endianness_32; + dest->endianness_64 = src->endianness_64; + dest->input_endianness_swap_func_32 = src->input_endianness_swap_func_32; + dest->input_endianness_swap_func_64 = src->input_endianness_swap_func_64; + dest->output_endianness_swap_func_32 = src->output_endianness_swap_func_32; + dest->output_endianness_swap_func_64 = src->output_endianness_swap_func_64; - /* 0x45670123 */ - else if ( *(const unsigned char*)&endianness_32 == 0x45 ) - { - tng_data->endianness_32 = TNG_BYTE_PAIR_SWAP_32; - } - } - { - static int64_t endianness_64 = 0x0123456789ABCDEFLL; - /* 0x0123456789ABCDEF */ - if ( *(const unsigned char*)&endianness_64 == 0x01 ) - { - tng_data->endianness_64 = TNG_BIG_ENDIAN_64; - } + dest->current_trajectory_frame_set.next_frame_set_file_pos = -1; + dest->current_trajectory_frame_set.prev_frame_set_file_pos = -1; + dest->current_trajectory_frame_set.n_frames = 0; - /* 0xEFCDAB8967452301 */ - else if ( *(const unsigned char*)&endianness_64 == 0xEF ) - { - tng_data->endianness_64 = TNG_LITTLE_ENDIAN_64; - } + return(TNG_SUCCESS); +} - /* 0x89ABCDEF01234567 */ - else if ( *(const unsigned char*)&endianness_64 == 0x89 ) - { - tng_data->endianness_64 = TNG_QUAD_SWAP_64; - } +tng_function_status DECLSPECDLLEXPORT tng_input_file_get + (const tng_trajectory_t tng_data, + char *file_name, + const int max_len) +{ + 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"); - /* 0x45670123CDEF89AB */ - else if ( *(const unsigned char*)&endianness_64 == 0x45 ) - { - tng_data->endianness_64 = TNG_BYTE_PAIR_SWAP_64; - } + strncpy(file_name, tng_data->input_file_path, max_len - 1); + file_name[max_len - 1] = 0; - /* 0x23016745AB89EFCD */ - else if ( *(const unsigned char*)&endianness_64 == 0x23 ) - { - tng_data->endianness_64 = TNG_BYTE_SWAP_64; - } + if(strlen(tng_data->input_file_path) > (unsigned int)max_len - 1) + { + return(TNG_FAILURE); } - - /* By default do not swap the byte order, i.e. keep the byte order of the - * architecture. The input file endianness will be set when reading the - * header. The output endianness can be changed - before the file is - * written. */ - tng_data->input_endianness_swap_func_32 = 0; - tng_data->input_endianness_swap_func_64 = 0; - tng_data->output_endianness_swap_func_32 = 0; - tng_data->output_endianness_swap_func_64 = 0; - - tng_data->current_trajectory_frame_set.next_frame_set_file_pos = -1; - tng_data->current_trajectory_frame_set.prev_frame_set_file_pos = -1; - tng_data->current_trajectory_frame_set.n_frames = 0; - return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_trajectory_destroy(tng_trajectory_t *tng_data_p) +tng_function_status DECLSPECDLLEXPORT tng_input_file_set + (const tng_trajectory_t tng_data, + const char *file_name) { - int64_t i, j, k, l; - int64_t n_particles, n_values_per_frame; - tng_trajectory_t tng_data = *tng_data_p; - tng_trajectory_frame_set_t frame_set; + unsigned int len; + char *temp; - if(!*tng_data_p) + 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->input_file_path && strcmp(tng_data->input_file_path, + file_name) == 0) { return(TNG_SUCCESS); } - frame_set = &tng_data->current_trajectory_frame_set; + if(tng_data->input_file) + { + fclose(tng_data->input_file); + } - if(tng_data->input_file_path) + len = tng_min_size(strlen(file_name) + 1, TNG_MAX_STR_LEN); + temp = realloc(tng_data->input_file_path, len); + if(!temp) { + fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, + __FILE__, __LINE__); free(tng_data->input_file_path); tng_data->input_file_path = 0; + return(TNG_CRITICAL); } + tng_data->input_file_path = temp; - if(tng_data->input_file) + strncpy(tng_data->input_file_path, file_name, len); + + return(tng_input_file_init(tng_data)); +} + +tng_function_status tng_output_file_get + (const tng_trajectory_t tng_data, + char *file_name, + const int max_len) +{ + 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"); + + strncpy(file_name, tng_data->output_file_path, max_len - 1); + file_name[max_len - 1] = 0; + + if(strlen(tng_data->output_file_path) > (unsigned int)max_len - 1) { - if(tng_data->output_file == tng_data->input_file) - { - tng_frame_set_finalize(tng_data, TNG_USE_HASH); - tng_data->output_file = 0; - } - fclose(tng_data->input_file); - tng_data->input_file = 0; + return(TNG_FAILURE); } + return(TNG_SUCCESS); +} - if(tng_data->output_file_path) +tng_function_status DECLSPECDLLEXPORT tng_output_file_set + (const 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) { - free(tng_data->output_file_path); - tng_data->output_file_path = 0; + return(TNG_SUCCESS); } if(tng_data->output_file) { - /* FIXME: Do not always write the hash */ - tng_frame_set_finalize(tng_data, TNG_USE_HASH); fclose(tng_data->output_file); - tng_data->output_file = 0; } - if(tng_data->first_program_name) + len = tng_min_size(strlen(file_name) + 1, TNG_MAX_STR_LEN); + temp = realloc(tng_data->output_file_path, len); + if(!temp) { - free(tng_data->first_program_name); - tng_data->first_program_name = 0; + fprintf(stderr, "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; - if(tng_data->last_program_name) + strncpy(tng_data->output_file_path, file_name, len); + + return(tng_output_file_init(tng_data)); +} + +tng_function_status DECLSPECDLLEXPORT tng_output_append_file_set + (const 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) { - free(tng_data->last_program_name); - tng_data->last_program_name = 0; + return(TNG_SUCCESS); } - if(tng_data->first_user_name) + if(tng_data->output_file) { - free(tng_data->first_user_name); - tng_data->first_user_name = 0; + fclose(tng_data->output_file); } - if(tng_data->last_user_name) - { - free(tng_data->last_user_name); - tng_data->last_user_name = 0; + len = tng_min_size(strlen(file_name) + 1, TNG_MAX_STR_LEN); + temp = realloc(tng_data->output_file_path, len); + if(!temp) + { + fprintf(stderr, "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; - if(tng_data->first_computer_name) + strncpy(tng_data->output_file_path, file_name, len); + + tng_data->output_file = fopen(tng_data->output_file_path, "rb+"); + if(!tng_data->output_file) { - free(tng_data->first_computer_name); - tng_data->first_computer_name = 0; + fprintf(stderr, "TNG library: Cannot open file %s. %s: %d\n", + tng_data->output_file_path, __FILE__, __LINE__); + return(TNG_CRITICAL); } + tng_data->input_file = tng_data->output_file; - if(tng_data->last_computer_name) + return(TNG_SUCCESS); +} + +tng_function_status DECLSPECDLLEXPORT tng_output_file_endianness_get + (const tng_trajectory_t tng_data, tng_file_endianness *endianness) +{ + tng_endianness_32 end_32; + tng_endianness_64 end_64; + + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(endianness, "TNG library: endianness must not be a NULL pointer"); + + if(tng_data->output_endianness_swap_func_32) { - free(tng_data->last_computer_name); - tng_data->last_computer_name = 0; + /* If other endianness variants are added they must be added here as well */ + if(tng_data->output_endianness_swap_func_32 == + &tng_swap_byte_order_big_endian_32) + { + end_32 = TNG_BIG_ENDIAN_32; + } + else if(tng_data->output_endianness_swap_func_32 == + &tng_swap_byte_order_little_endian_32) + { + end_32 = TNG_LITTLE_ENDIAN_32; + } + else + { + return(TNG_FAILURE); + } } - - if(tng_data->first_pgp_signature) + else { - free(tng_data->first_pgp_signature); - tng_data->first_pgp_signature = 0; + end_32 = (tng_endianness_32)tng_data->endianness_32; } - if(tng_data->last_pgp_signature) + if(tng_data->output_endianness_swap_func_64) { - free(tng_data->last_pgp_signature); - tng_data->last_pgp_signature = 0; + /* If other endianness variants are added they must be added here as well */ + if(tng_data->output_endianness_swap_func_64 == + &tng_swap_byte_order_big_endian_64) + { + end_64 = TNG_BIG_ENDIAN_64; + } + else if(tng_data->output_endianness_swap_func_64 == + &tng_swap_byte_order_little_endian_64) + { + end_64 = TNG_LITTLE_ENDIAN_64; + } + else + { + return(TNG_FAILURE); + } } - - if(tng_data->forcefield_name) + else { - free(tng_data->forcefield_name); - tng_data->forcefield_name = 0; + end_64 = (tng_endianness_64)tng_data->endianness_64; } - tng_frame_set_particle_mapping_free(tng_data); + if((int)end_32 != (int)end_64) + { + return(TNG_FAILURE); + } - if(frame_set->molecule_cnt_list) + if(end_32 == TNG_LITTLE_ENDIAN_32) { - free(frame_set->molecule_cnt_list); - frame_set->molecule_cnt_list = 0; + *endianness = TNG_LITTLE_ENDIAN; } - if(tng_data->var_num_atoms_flag) + else if(end_32 == TNG_BIG_ENDIAN_32) { - n_particles = frame_set->n_particles; + *endianness = TNG_BIG_ENDIAN; } else { - n_particles = tng_data->n_particles; + return(TNG_FAILURE); } - if(tng_data->non_tr_particle_data) - { - for(i = 0; i < tng_data->n_particle_data_blocks; i++) - { - if(tng_data->non_tr_particle_data[i].values) - { - free(tng_data->non_tr_particle_data[i].values); - tng_data->non_tr_particle_data[i].values = 0; - } + return(TNG_SUCCESS); +} - if(tng_data->non_tr_particle_data[i].strings) - { - n_values_per_frame = tng_data->non_tr_particle_data[i]. - n_values_per_frame; - if(tng_data->non_tr_particle_data[i].strings[0]) - { - for(j = 0; j < n_particles; j++) - { - if(tng_data->non_tr_particle_data[i].strings[0][j]) - { - for(k = 0; k < n_values_per_frame; k++) - { - if(tng_data->non_tr_particle_data[i]. - strings[0][j][k]) - { - free(tng_data->non_tr_particle_data[i]. - strings[0][j][k]); - tng_data->non_tr_particle_data[i]. - strings[0][j][k] = 0; - } - } - free(tng_data->non_tr_particle_data[i]. - strings[0][j]); - tng_data->non_tr_particle_data[i].strings[0][j] = 0; - } - } - free(tng_data->non_tr_particle_data[i].strings[0]); - tng_data->non_tr_particle_data[i].strings[0] = 0; - } - free(tng_data->non_tr_particle_data[i].strings); - tng_data->non_tr_particle_data[i].strings = 0; - } +tng_function_status DECLSPECDLLEXPORT tng_output_file_endianness_set + (const tng_trajectory_t tng_data, + const tng_file_endianness endianness) +{ + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - if(tng_data->non_tr_particle_data[i].block_name) - { - free(tng_data->non_tr_particle_data[i].block_name); - tng_data->non_tr_particle_data[i].block_name = 0; - } - } - free(tng_data->non_tr_particle_data); - tng_data->non_tr_particle_data = 0; + /* Tne endianness cannot be changed if the data has already been written + * to the output file. */ + if(ftello(tng_data->output_file) > 0) + { + return(TNG_FAILURE); } - if(tng_data->non_tr_data) + if(endianness == TNG_BIG_ENDIAN) { - for(i = 0; i < tng_data->n_data_blocks; i++) + if(tng_data->endianness_32 == TNG_BIG_ENDIAN_32) { - if(tng_data->non_tr_data[i].values) - { - free(tng_data->non_tr_data[i].values); - tng_data->non_tr_data[i].values = 0; - } - - if(tng_data->non_tr_data[i].strings) - { - n_values_per_frame = tng_data->non_tr_data[i]. - n_values_per_frame; - if(tng_data->non_tr_data[i].strings[0]) - { - for(j = 0; j < n_values_per_frame; j++) - { - if(tng_data->non_tr_data[i].strings[0][j]) - { - free(tng_data->non_tr_data[i].strings[0][j]); - tng_data->non_tr_data[i].strings[0][j] = 0; - } - } - free(tng_data->non_tr_data[i].strings[0]); - tng_data->non_tr_data[i].strings[0] = 0; - } - free(tng_data->non_tr_data[i].strings); - tng_data->non_tr_data[i].strings = 0; - } - - if(tng_data->non_tr_data[i].block_name) - { - free(tng_data->non_tr_data[i].block_name); - tng_data->non_tr_data[i].block_name = 0; - } + tng_data->output_endianness_swap_func_32 = 0; } - free(tng_data->non_tr_data); - tng_data->non_tr_data = 0; - } - - tng_data->n_particle_data_blocks = 0; - tng_data->n_data_blocks = 0; - - if(tng_data->compress_algo_pos) - { - free(tng_data->compress_algo_pos); - tng_data->compress_algo_pos = 0; + else + { + tng_data->output_endianness_swap_func_32 = + &tng_swap_byte_order_big_endian_32; + } + if(tng_data->endianness_64 == TNG_BIG_ENDIAN_64) + { + tng_data->output_endianness_swap_func_64 = 0; + } + else + { + tng_data->output_endianness_swap_func_64 = + &tng_swap_byte_order_big_endian_64; + } + return(TNG_SUCCESS); } - if(tng_data->compress_algo_vel) + else if(endianness == TNG_LITTLE_ENDIAN) { - free(tng_data->compress_algo_vel); - tng_data->compress_algo_vel = 0; + if(tng_data->endianness_32 == TNG_LITTLE_ENDIAN_32) + { + tng_data->output_endianness_swap_func_32 = 0; + } + else + { + tng_data->output_endianness_swap_func_32 = + &tng_swap_byte_order_little_endian_32; + } + if(tng_data->endianness_64 == TNG_LITTLE_ENDIAN_64) + { + tng_data->output_endianness_swap_func_64 = 0; + } + else + { + tng_data->output_endianness_swap_func_64 = + &tng_swap_byte_order_little_endian_64; + } + return(TNG_SUCCESS); } - if(frame_set->tr_particle_data) - { - for(i = 0; i < frame_set->n_particle_data_blocks; i++) - { - if(frame_set->tr_particle_data[i].values) - { - free(frame_set->tr_particle_data[i].values); - frame_set->tr_particle_data[i].values = 0; - } + /* If the specified endianness is neither big nor little endian return a + * failure. */ + return(TNG_FAILURE); +} - if(frame_set->tr_particle_data[i].strings) - { - n_values_per_frame = frame_set->tr_particle_data[i]. - n_values_per_frame; - for(j = 0; j < frame_set->tr_particle_data[i].n_frames; j++) - { - if(frame_set->tr_particle_data[i].strings[j]) - { - for(k = 0; k < n_particles; k++) - { - if(frame_set->tr_particle_data[i]. - strings[j][k]) - { - for(l = 0; l < n_values_per_frame; l++) - { - if(frame_set->tr_particle_data[i]. - strings[j][k][l]) - { - free(frame_set->tr_particle_data[i]. - strings[j][k][l]); - frame_set->tr_particle_data[i]. - strings[j][k][l] = 0; - } - } - free(frame_set->tr_particle_data[i]. - strings[j][k]); - frame_set->tr_particle_data[i]. - strings[j][k] = 0; - } - } - free(frame_set->tr_particle_data[i].strings[j]); - frame_set->tr_particle_data[i].strings[j] = 0; - } - } - free(frame_set->tr_particle_data[i].strings); - frame_set->tr_particle_data[i].strings = 0; - } - - if(frame_set->tr_particle_data[i].block_name) - { - free(frame_set->tr_particle_data[i].block_name); - frame_set->tr_particle_data[i].block_name = 0; - } - } - free(frame_set->tr_particle_data); - frame_set->tr_particle_data = 0; - } - - if(frame_set->tr_data) - { - for(i = 0; i < frame_set->n_data_blocks; i++) - { - if(frame_set->tr_data[i].values) - { - free(frame_set->tr_data[i].values); - frame_set->tr_data[i].values = 0; - } - - if(frame_set->tr_data[i].strings) - { - n_values_per_frame = frame_set->tr_data[i]. - n_values_per_frame; - for(j = 0; j < frame_set->tr_data[i].n_frames; j++) - { - if(frame_set->tr_data[i].strings[j]) - { - for(k = 0; k < n_values_per_frame; k++) - { - if(frame_set->tr_data[i].strings[j][k]) - { - free(frame_set->tr_data[i].strings[j][k]); - frame_set->tr_data[i].strings[j][k] = 0; - } - } - free(frame_set->tr_data[i].strings[j]); - frame_set->tr_data[i].strings[j] = 0; - } - } - free(frame_set->tr_data[i].strings); - frame_set->tr_data[i].strings = 0; - } - - if(frame_set->tr_data[i].block_name) - { - free(frame_set->tr_data[i].block_name); - frame_set->tr_data[i].block_name = 0; - } - } - free(frame_set->tr_data); - frame_set->tr_data = 0; - } +tng_function_status DECLSPECDLLEXPORT tng_first_program_name_get + (const tng_trajectory_t tng_data, + char *name, + const int max_len) +{ + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); - frame_set->n_particle_data_blocks = 0; - frame_set->n_data_blocks = 0; + strncpy(name, tng_data->first_program_name, max_len - 1); + name[max_len - 1] = 0; - if(tng_data->molecules) - { - for(i = 0; i < tng_data->n_molecules; i++) - { - tng_molecule_destroy(tng_data, &tng_data->molecules[i]); - } - free(tng_data->molecules); - tng_data->molecules = 0; - tng_data->n_molecules = 0; - } - if(tng_data->molecule_cnt_list) + if(strlen(tng_data->first_program_name) > (unsigned int)max_len - 1) { - free(tng_data->molecule_cnt_list); - tng_data->molecule_cnt_list = 0; + return(TNG_FAILURE); } - - free(*tng_data_p); - *tng_data_p = 0; - return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_trajectory_init_from_src(tng_trajectory_t src, - tng_trajectory_t *dest_p) +tng_function_status DECLSPECDLLEXPORT tng_first_program_name_set + (const tng_trajectory_t tng_data, + const char *new_name) { - tng_trajectory_frame_set_t frame_set; - tng_trajectory_t dest; - - TNG_ASSERT(src != 0, "TNG library: Source trajectory must not be NULL."); - - *dest_p = malloc(sizeof(struct tng_trajectory)); - if(!*dest_p) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%"TNG_PRIsize" bytes). %s: %d\n", - sizeof(struct tng_trajectory), __FILE__, __LINE__); - return(TNG_CRITICAL); - } + unsigned int len; - dest = *dest_p; + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer"); - frame_set = &dest->current_trajectory_frame_set; + len = tng_min_size(strlen(new_name) + 1, TNG_MAX_STR_LEN); - dest->input_file_path = malloc(strlen(src->input_file_path) + 1); - if(!dest->input_file_path) + if(tng_data->first_program_name && strlen(tng_data->first_program_name) < len) { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", - (int)strlen(src->input_file_path) + 1, __FILE__, __LINE__); - return(TNG_CRITICAL); + free(tng_data->first_program_name); + tng_data->first_program_name = 0; } - strcpy(dest->input_file_path, src->input_file_path); - dest->input_file = 0; - dest->input_file_len = src->input_file_len; - dest->output_file_path = malloc(strlen(src->output_file_path) + 1); - if(!dest->output_file_path) + if(!tng_data->first_program_name) { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", - (int)strlen(src->output_file_path) + 1, __FILE__, __LINE__); - return(TNG_CRITICAL); + tng_data->first_program_name = malloc(len); + if(!tng_data->first_program_name) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, + __FILE__, __LINE__); + return(TNG_CRITICAL); + } } - strcpy(dest->output_file_path, src->output_file_path); - dest->output_file = 0; - - dest->first_program_name = 0; - dest->first_user_name = 0; - dest->first_computer_name = 0; - dest->first_pgp_signature = 0; - dest->last_program_name = 0; - dest->last_user_name = 0; - dest->last_computer_name = 0; - dest->last_pgp_signature = 0; - dest->forcefield_name = 0; - - dest->var_num_atoms_flag = src->var_num_atoms_flag; - dest->first_trajectory_frame_set_input_file_pos = - src->first_trajectory_frame_set_input_file_pos; - dest->last_trajectory_frame_set_input_file_pos = - src->last_trajectory_frame_set_input_file_pos; - dest->current_trajectory_frame_set_input_file_pos = - src->current_trajectory_frame_set_input_file_pos; - dest->first_trajectory_frame_set_output_file_pos = - src->first_trajectory_frame_set_output_file_pos; - dest->last_trajectory_frame_set_output_file_pos = - src->last_trajectory_frame_set_output_file_pos; - dest->current_trajectory_frame_set_output_file_pos = - src->current_trajectory_frame_set_output_file_pos; - dest->frame_set_n_frames = src->frame_set_n_frames; - dest->n_trajectory_frame_sets = src->n_trajectory_frame_sets; - dest->medium_stride_length = src->medium_stride_length; - dest->long_stride_length = src->long_stride_length; - - dest->time_per_frame = src->time_per_frame; - - /* Currently the non trajectory data blocks are not copied since it - * can lead to problems when freeing memory in a parallel block. */ - dest->n_particle_data_blocks = 0; - dest->n_data_blocks = 0; - dest->non_tr_particle_data = 0; - dest->non_tr_data = 0; - - dest->compress_algo_pos = 0; - dest->compress_algo_vel = 0; - dest->distance_unit_exponential = -9; - dest->compression_precision = 1000; - - frame_set->n_mapping_blocks = 0; - frame_set->mappings = 0; - frame_set->molecule_cnt_list = 0; - - frame_set->n_particle_data_blocks = 0; - frame_set->n_data_blocks = 0; - - frame_set->tr_particle_data = 0; - frame_set->tr_data = 0; - - frame_set->next_frame_set_file_pos = -1; - frame_set->prev_frame_set_file_pos = -1; - frame_set->medium_stride_next_frame_set_file_pos = -1; - frame_set->medium_stride_prev_frame_set_file_pos = -1; - frame_set->long_stride_next_frame_set_file_pos = -1; - frame_set->long_stride_prev_frame_set_file_pos = -1; - frame_set->first_frame = -1; - - dest->n_molecules = 0; - dest->molecules = 0; - dest->molecule_cnt_list = 0; - dest->n_particles = src->n_particles; - - dest->endianness_32 = src->endianness_32; - dest->endianness_64 = src->endianness_64; - dest->input_endianness_swap_func_32 = src->input_endianness_swap_func_32; - dest->input_endianness_swap_func_64 = src->input_endianness_swap_func_64; - dest->output_endianness_swap_func_32 = src->output_endianness_swap_func_32; - dest->output_endianness_swap_func_64 = src->output_endianness_swap_func_64; - dest->current_trajectory_frame_set.next_frame_set_file_pos = -1; - dest->current_trajectory_frame_set.prev_frame_set_file_pos = -1; - dest->current_trajectory_frame_set.n_frames = 0; + strncpy(tng_data->first_program_name, new_name, len); return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_input_file_get(const tng_trajectory_t tng_data, - char *file_name, const int max_len) +tng_function_status DECLSPECDLLEXPORT tng_last_program_name_get + (const tng_trajectory_t tng_data, + char *name, const int max_len) { 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"); + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); - strncpy(file_name, tng_data->input_file_path, max_len - 1); - file_name[max_len - 1] = 0; + strncpy(name, tng_data->last_program_name, max_len - 1); + name[max_len - 1] = 0; - if(strlen(tng_data->input_file_path) > (unsigned int)max_len - 1) + if(strlen(tng_data->last_program_name) > (unsigned int)max_len - 1) { return(TNG_FAILURE); } return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_input_file_set(tng_trajectory_t tng_data, - const char *file_name) +tng_function_status DECLSPECDLLEXPORT tng_last_program_name_set + (const tng_trajectory_t tng_data, + const char *new_name) { unsigned 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"); + TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer"); + len = tng_min_size(strlen(new_name) + 1, TNG_MAX_STR_LEN); - if(tng_data->input_file_path && strcmp(tng_data->input_file_path, - file_name) == 0) + if(tng_data->last_program_name && strlen(tng_data->last_program_name) < len) { - return(TNG_SUCCESS); + free(tng_data->last_program_name); + tng_data->last_program_name = 0; } - - if(tng_data->input_file) + if(!tng_data->last_program_name) { - fclose(tng_data->input_file); - } - - len = tng_min_i((int)strlen(file_name) + 1, TNG_MAX_STR_LEN); - temp = realloc(tng_data->input_file_path, len); - if(!temp) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, - __FILE__, __LINE__); - free(tng_data->input_file_path); - tng_data->input_file_path = 0; - return(TNG_CRITICAL); + tng_data->last_program_name = malloc(len); + if(!tng_data->last_program_name) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, + __FILE__, __LINE__); + return(TNG_CRITICAL); + } } - tng_data->input_file_path = temp; - strncpy(tng_data->input_file_path, file_name, len); + strncpy(tng_data->last_program_name, new_name, len); - return(tng_input_file_init(tng_data)); + return(TNG_SUCCESS); } -tng_function_status tng_output_file_get(const tng_trajectory_t tng_data, - char *file_name, const int max_len) +tng_function_status DECLSPECDLLEXPORT tng_first_user_name_get + (const tng_trajectory_t tng_data, + char *name, const int max_len) { 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"); + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); - strncpy(file_name, tng_data->output_file_path, max_len - 1); - file_name[max_len - 1] = 0; + strncpy(name, tng_data->first_user_name, max_len - 1); + name[max_len - 1] = 0; - if(strlen(tng_data->output_file_path) > (unsigned int)max_len - 1) + if(strlen(tng_data->first_user_name) > (unsigned int)max_len - 1) { return(TNG_FAILURE); } return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_output_file_set(tng_trajectory_t tng_data, - const char *file_name) +tng_function_status DECLSPECDLLEXPORT tng_first_user_name_set + (const tng_trajectory_t tng_data, + const char *new_name) { - int len; - char *temp; + unsigned int len; 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"); + TNG_ASSERT(new_name, "TNG library: new_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); - } + len = tng_min_size(strlen(new_name) + 1, TNG_MAX_STR_LEN); - if(tng_data->output_file) + /* If the currently stored string length is not enough to store the new + * string it is freed and reallocated. */ + if(tng_data->first_user_name && strlen(tng_data->first_user_name) < len) { - fclose(tng_data->output_file); + free(tng_data->first_user_name); + tng_data->first_user_name = 0; } - - len = tng_min_i((int)strlen(file_name) + 1, TNG_MAX_STR_LEN); - temp = realloc(tng_data->output_file_path, len); - if(!temp) + if(!tng_data->first_user_name) { - fprintf(stderr, "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->first_user_name = malloc(len); + if(!tng_data->first_user_name) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, + __FILE__, __LINE__); + return(TNG_CRITICAL); + } } - tng_data->output_file_path = temp; - strncpy(tng_data->output_file_path, file_name, len); + strncpy(tng_data->first_user_name, new_name, len); - return(tng_output_file_init(tng_data)); + return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_output_append_file_set - (tng_trajectory_t tng_data, - const char *file_name) +tng_function_status DECLSPECDLLEXPORT tng_last_user_name_get + (const tng_trajectory_t tng_data, + char *name, const int max_len) { - 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) - { - fprintf(stderr, "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; + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); - strncpy(tng_data->output_file_path, file_name, len); + strncpy(name, tng_data->last_user_name, max_len - 1); + name[max_len - 1] = 0; - tng_data->output_file = fopen(tng_data->output_file_path, "rb+"); - if(!tng_data->output_file) + if(strlen(tng_data->last_user_name) > (unsigned int)max_len - 1) { - fprintf(stderr, "TNG library: Cannot open file %s. %s: %d\n", - tng_data->output_file_path, __FILE__, __LINE__); - return(TNG_CRITICAL); + return(TNG_FAILURE); } - tng_data->input_file = tng_data->output_file; - return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_output_file_endianness_get - (const tng_trajectory_t tng_data, tng_file_endianness *endianness) +tng_function_status DECLSPECDLLEXPORT tng_last_user_name_set + (const tng_trajectory_t tng_data, + const char *new_name) { - tng_endianness_32 end_32; - tng_endianness_64 end_64; + unsigned int len; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(endianness, "TNG library: endianness must not be a NULL pointer"); + TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer"); - if(tng_data->output_endianness_swap_func_32) - { - /* If other endianness variants are added they must be added here as well */ - if(tng_data->output_endianness_swap_func_32 == - &tng_swap_byte_order_big_endian_32) - { - end_32 = TNG_BIG_ENDIAN_32; - } - else if(tng_data->output_endianness_swap_func_32 == - &tng_swap_byte_order_little_endian_32) - { - end_32 = TNG_LITTLE_ENDIAN_32; - } - else - { - return(TNG_FAILURE); - } - } - else + len = tng_min_size(strlen(new_name) + 1, TNG_MAX_STR_LEN); + + /* If the currently stored string length is not enough to store the new + * string it is freed and reallocated. */ + if(tng_data->last_user_name && strlen(tng_data->last_user_name) < len) { - end_32 = (tng_endianness_32)tng_data->endianness_32; + free(tng_data->last_user_name); + tng_data->last_user_name = 0; } - - if(tng_data->output_endianness_swap_func_64) + if(!tng_data->last_user_name) { - /* If other endianness variants are added they must be added here as well */ - if(tng_data->output_endianness_swap_func_64 == - &tng_swap_byte_order_big_endian_64) - { - end_64 = TNG_BIG_ENDIAN_64; - } - else if(tng_data->output_endianness_swap_func_64 == - &tng_swap_byte_order_little_endian_64) - { - end_64 = TNG_LITTLE_ENDIAN_64; - } - else + tng_data->last_user_name = malloc(len); + if(!tng_data->last_user_name) { - return(TNG_FAILURE); + fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, + __FILE__, __LINE__); + return(TNG_CRITICAL); } } - else - { - end_64 = (tng_endianness_64)tng_data->endianness_64; - } - if((int)end_32 != (int)end_64) + strncpy(tng_data->last_user_name, new_name, len); + + return(TNG_SUCCESS); +} + +tng_function_status DECLSPECDLLEXPORT tng_first_computer_name_get + (const tng_trajectory_t tng_data, + char *name, const int max_len) +{ + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); + + strncpy(name, tng_data->first_computer_name, max_len - 1); + name[max_len - 1] = 0; + + if(strlen(tng_data->first_computer_name) > (unsigned int)max_len - 1) { return(TNG_FAILURE); } + return(TNG_SUCCESS); +} - if(end_32 == TNG_LITTLE_ENDIAN_32) - { - *endianness = TNG_LITTLE_ENDIAN; - } +tng_function_status DECLSPECDLLEXPORT tng_first_computer_name_set + (const tng_trajectory_t tng_data, + const char *new_name) +{ + unsigned int len; - else if(end_32 == TNG_BIG_ENDIAN_32) + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer"); + + len = tng_min_size(strlen(new_name) + 1, TNG_MAX_STR_LEN); + + /* If the currently stored string length is not enough to store the new + * string it is freed and reallocated. */ + if(tng_data->first_computer_name && strlen(tng_data->first_computer_name) < len) { - *endianness = TNG_BIG_ENDIAN; + free(tng_data->first_computer_name); + tng_data->first_computer_name = 0; } - else + if(!tng_data->first_computer_name) { - return(TNG_FAILURE); + tng_data->first_computer_name = malloc(len); + if(!tng_data->first_computer_name) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, + __FILE__, __LINE__); + return(TNG_CRITICAL); + } } + strncpy(tng_data->first_computer_name, new_name, len); + return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_output_file_endianness_set - (tng_trajectory_t tng_data, - const tng_file_endianness endianness) +tng_function_status DECLSPECDLLEXPORT tng_last_computer_name_get + (const tng_trajectory_t tng_data, + char *name, const int max_len) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); - /* Tne endianness cannot be changed if the data has already been written - * to the output file. */ - if(ftello(tng_data->output_file) > 0) + strncpy(name, tng_data->last_computer_name, max_len - 1); + name[max_len - 1] = 0; + + if(strlen(tng_data->last_computer_name) > (unsigned int)max_len - 1) { return(TNG_FAILURE); } + return(TNG_SUCCESS); +} - if(endianness == TNG_BIG_ENDIAN) - { - if(tng_data->endianness_32 == TNG_BIG_ENDIAN_32) - { - tng_data->output_endianness_swap_func_32 = 0; - } - else - { - tng_data->output_endianness_swap_func_32 = - &tng_swap_byte_order_big_endian_32; - } - if(tng_data->endianness_64 == TNG_BIG_ENDIAN_64) - { - tng_data->output_endianness_swap_func_64 = 0; - } - else - { - tng_data->output_endianness_swap_func_64 = - &tng_swap_byte_order_big_endian_64; - } - return(TNG_SUCCESS); - } - else if(endianness == TNG_LITTLE_ENDIAN) - { - if(tng_data->endianness_32 == TNG_LITTLE_ENDIAN_32) - { - tng_data->output_endianness_swap_func_32 = 0; - } - else - { - tng_data->output_endianness_swap_func_32 = - &tng_swap_byte_order_little_endian_32; - } - if(tng_data->endianness_64 == TNG_LITTLE_ENDIAN_64) - { - tng_data->output_endianness_swap_func_64 = 0; - } - else - { - tng_data->output_endianness_swap_func_64 = - &tng_swap_byte_order_little_endian_64; - } - return(TNG_SUCCESS); - } - - /* If the specified endianness is neither big nor little endian return a - * failure. */ - return(TNG_FAILURE); -} - -tng_function_status DECLSPECDLLEXPORT tng_first_program_name_get +tng_function_status DECLSPECDLLEXPORT tng_last_computer_name_set (const tng_trajectory_t tng_data, - char *name, const int max_len) -{ - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); - - strncpy(name, tng_data->first_program_name, max_len - 1); - name[max_len - 1] = 0; - - if(strlen(tng_data->first_program_name) > (unsigned int)max_len - 1) - { - return(TNG_FAILURE); - } - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_first_program_name_set(tng_trajectory_t tng_data, - const char *new_name) + const char *new_name) { unsigned int len; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer"); - len = tng_min_i((int)strlen(new_name) + 1, TNG_MAX_STR_LEN); + len = tng_min_size(strlen(new_name) + 1, TNG_MAX_STR_LEN); - if(tng_data->first_program_name && strlen(tng_data->first_program_name) < len) + /* If the currently stored string length is not enough to store the new + * string it is freed and reallocated. */ + if(tng_data->last_computer_name && strlen(tng_data->last_computer_name) < + len) { - free(tng_data->first_program_name); - tng_data->first_program_name = 0; + free(tng_data->last_computer_name); + tng_data->last_computer_name = 0; } - if(!tng_data->first_program_name) + if(!tng_data->last_computer_name) { - tng_data->first_program_name = malloc(len); - if(!tng_data->first_program_name) + tng_data->last_computer_name = malloc(len); + if(!tng_data->last_computer_name) { fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, __FILE__, __LINE__); @@ -10764,48 +9958,51 @@ tng_function_status DECLSPECDLLEXPORT tng_first_program_name_set(tng_trajectory_ } } - strncpy(tng_data->first_program_name, new_name, len); + strncpy(tng_data->last_computer_name, new_name, len); return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_last_program_name_get +tng_function_status DECLSPECDLLEXPORT tng_first_signature_get (const tng_trajectory_t tng_data, - char *name, const int max_len) + char *signature, const int max_len) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); + TNG_ASSERT(signature, "TNG library: signature must not be a NULL pointer"); - strncpy(name, tng_data->last_program_name, max_len - 1); - name[max_len - 1] = 0; + strncpy(signature, tng_data->first_pgp_signature, max_len - 1); + signature[max_len - 1] = 0; - if(strlen(tng_data->last_program_name) > (unsigned int)max_len - 1) + if(strlen(tng_data->first_pgp_signature) > (unsigned int)max_len - 1) { return(TNG_FAILURE); } return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_last_program_name_set - (tng_trajectory_t tng_data, - const char *new_name) +tng_function_status DECLSPECDLLEXPORT tng_first_signature_set + (const tng_trajectory_t tng_data, + const char *signature) { unsigned int len; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer"); + TNG_ASSERT(signature, "TNG library: signature must not be a NULL pointer"); - len = tng_min_i((int)strlen(new_name) + 1, TNG_MAX_STR_LEN); + len = tng_min_size(strlen(signature) + 1, TNG_MAX_STR_LEN); - if(tng_data->last_program_name && strlen(tng_data->last_program_name) < len) + /* If the currently stored string length is not enough to store the new + * string it is freed and reallocated. */ + if(tng_data->first_pgp_signature && strlen(tng_data->first_pgp_signature) < + len) { - free(tng_data->last_program_name); - tng_data->last_program_name = 0; + free(tng_data->first_pgp_signature); + tng_data->first_pgp_signature = 0; } - if(!tng_data->last_program_name) + if(!tng_data->first_pgp_signature) { - tng_data->last_program_name = malloc(len); - if(!tng_data->last_program_name) + tng_data->first_pgp_signature = malloc(len); + if(!tng_data->first_pgp_signature) { fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, __FILE__, __LINE__); @@ -10813,50 +10010,51 @@ tng_function_status DECLSPECDLLEXPORT tng_last_program_name_set } } - strncpy(tng_data->last_program_name, new_name, len); + strncpy(tng_data->first_pgp_signature, signature, len); return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_first_user_name_get +tng_function_status DECLSPECDLLEXPORT tng_last_signature_get (const tng_trajectory_t tng_data, - char *name, const int max_len) + char *signature, const int max_len) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); + TNG_ASSERT(signature, "TNG library: signature must not be a NULL pointer"); - strncpy(name, tng_data->first_user_name, max_len - 1); - name[max_len - 1] = 0; + strncpy(signature, tng_data->last_pgp_signature, max_len - 1); + signature[max_len - 1] = 0; - if(strlen(tng_data->first_user_name) > (unsigned int)max_len - 1) + if(strlen(tng_data->last_pgp_signature) > (unsigned int)max_len - 1) { return(TNG_FAILURE); } return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_first_user_name_set - (tng_trajectory_t tng_data, - const char *new_name) +tng_function_status DECLSPECDLLEXPORT tng_last_signature_set + (const tng_trajectory_t tng_data, + const char *signature) { unsigned int len; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer"); + TNG_ASSERT(signature, "TNG library: signature must not be a NULL pointer"); - len = tng_min_i((int)strlen(new_name) + 1, TNG_MAX_STR_LEN); + len = tng_min_size(strlen(signature) + 1, TNG_MAX_STR_LEN); /* If the currently stored string length is not enough to store the new * string it is freed and reallocated. */ - if(tng_data->first_user_name && strlen(tng_data->first_user_name) < len) + if(tng_data->last_pgp_signature && strlen(tng_data->last_pgp_signature) < + len) { - free(tng_data->first_user_name); - tng_data->first_user_name = 0; + free(tng_data->last_pgp_signature); + tng_data->last_pgp_signature = 0; } - if(!tng_data->first_user_name) + if(!tng_data->last_pgp_signature) { - tng_data->first_user_name = malloc(len); - if(!tng_data->first_user_name) + tng_data->last_pgp_signature = malloc(len); + if(!tng_data->last_pgp_signature) { fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, __FILE__, __LINE__); @@ -10864,30 +10062,30 @@ tng_function_status DECLSPECDLLEXPORT tng_first_user_name_set } } - strncpy(tng_data->first_user_name, new_name, len); + strncpy(tng_data->last_pgp_signature, signature, len); return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_last_user_name_get +tng_function_status DECLSPECDLLEXPORT tng_forcefield_name_get (const tng_trajectory_t tng_data, char *name, const int max_len) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); - strncpy(name, tng_data->last_user_name, max_len - 1); + strncpy(name, tng_data->forcefield_name, max_len - 1); name[max_len - 1] = 0; - if(strlen(tng_data->last_user_name) > (unsigned int)max_len - 1) + if(strlen(tng_data->forcefield_name) > (unsigned int)max_len - 1) { return(TNG_FAILURE); } return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_last_user_name_set - (tng_trajectory_t tng_data, +tng_function_status DECLSPECDLLEXPORT tng_forcefield_name_set + (const tng_trajectory_t tng_data, const char *new_name) { unsigned int len; @@ -10895,19 +10093,19 @@ tng_function_status DECLSPECDLLEXPORT tng_last_user_name_set TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer"); - len = tng_min_i((int)strlen(new_name) + 1, TNG_MAX_STR_LEN); + len = tng_min_size(strlen(new_name) + 1, TNG_MAX_STR_LEN); /* If the currently stored string length is not enough to store the new * string it is freed and reallocated. */ - if(tng_data->last_user_name && strlen(tng_data->last_user_name) < len) + if(tng_data->forcefield_name && strlen(tng_data->forcefield_name) < len) { - free(tng_data->last_user_name); - tng_data->last_user_name = 0; + free(tng_data->forcefield_name); + tng_data->forcefield_name = 0; } - if(!tng_data->last_user_name) + if(!tng_data->forcefield_name) { - tng_data->last_user_name = malloc(len); - if(!tng_data->last_user_name) + tng_data->forcefield_name = malloc(len); + if(!tng_data->forcefield_name) { fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, __FILE__, __LINE__); @@ -10915,319 +10113,61 @@ tng_function_status DECLSPECDLLEXPORT tng_last_user_name_set } } - strncpy(tng_data->last_user_name, new_name, len); + strncpy(tng_data->forcefield_name, new_name, len); return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_first_computer_name_get +tng_function_status DECLSPECDLLEXPORT tng_medium_stride_length_get (const tng_trajectory_t tng_data, - char *name, const int max_len) + int64_t *len) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); + TNG_ASSERT(len, "TNG library: len must not be a NULL pointer"); - strncpy(name, tng_data->first_computer_name, max_len - 1); - name[max_len - 1] = 0; + *len = tng_data->medium_stride_length; - if(strlen(tng_data->first_computer_name) > (unsigned int)max_len - 1) - { - return(TNG_FAILURE); - } return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_first_computer_name_set - (tng_trajectory_t tng_data, - const char *new_name) +tng_function_status DECLSPECDLLEXPORT tng_medium_stride_length_set + (const tng_trajectory_t tng_data, + const int64_t len) { - unsigned int len; - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer"); - - len = tng_min_i((int)strlen(new_name) + 1, TNG_MAX_STR_LEN); - /* If the currently stored string length is not enough to store the new - * string it is freed and reallocated. */ - if(tng_data->first_computer_name && strlen(tng_data->first_computer_name) < len) - { - free(tng_data->first_computer_name); - tng_data->first_computer_name = 0; - } - if(!tng_data->first_computer_name) + if(len >= tng_data->long_stride_length) { - tng_data->first_computer_name = malloc(len); - if(!tng_data->first_computer_name) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, - __FILE__, __LINE__); - return(TNG_CRITICAL); - } + return(TNG_FAILURE); } - - strncpy(tng_data->first_computer_name, new_name, len); + tng_data->medium_stride_length = len; return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_last_computer_name_get - (const tng_trajectory_t tng_data, - char *name, const int max_len) +tng_function_status DECLSPECDLLEXPORT tng_long_stride_length_get + (const tng_trajectory_t tng_data, + int64_t *len) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); + TNG_ASSERT(len, "TNG library: len must not be a NULL pointer"); - strncpy(name, tng_data->last_computer_name, max_len - 1); - name[max_len - 1] = 0; + *len = tng_data->long_stride_length; - if(strlen(tng_data->last_computer_name) > (unsigned int)max_len - 1) - { - return(TNG_FAILURE); - } return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_last_computer_name_set - (tng_trajectory_t tng_data, - const char *new_name) +tng_function_status DECLSPECDLLEXPORT tng_long_stride_length_set + (const tng_trajectory_t tng_data, + const int64_t len) { - unsigned int len; - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer"); - - len = tng_min_i((int)strlen(new_name) + 1, TNG_MAX_STR_LEN); - /* If the currently stored string length is not enough to store the new - * string it is freed and reallocated. */ - if(tng_data->last_computer_name && strlen(tng_data->last_computer_name) < - len) - { - free(tng_data->last_computer_name); - tng_data->last_computer_name = 0; - } - if(!tng_data->last_computer_name) + if(len <= tng_data->medium_stride_length) { - tng_data->last_computer_name = malloc(len); - if(!tng_data->last_computer_name) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, - __FILE__, __LINE__); - return(TNG_CRITICAL); - } + return(TNG_FAILURE); } - - strncpy(tng_data->last_computer_name, new_name, len); - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_first_signature_get - (const tng_trajectory_t tng_data, - char *signature, const int max_len) -{ - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(signature, "TNG library: signature must not be a NULL pointer"); - - strncpy(signature, tng_data->first_pgp_signature, max_len - 1); - signature[max_len - 1] = 0; - - if(strlen(tng_data->first_pgp_signature) > (unsigned int)max_len - 1) - { - return(TNG_FAILURE); - } - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_first_signature_set - (tng_trajectory_t tng_data, - const char *signature) -{ - unsigned int len; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(signature, "TNG library: signature must not be a NULL pointer"); - - len = tng_min_i((int)strlen(signature) + 1, TNG_MAX_STR_LEN); - - /* If the currently stored string length is not enough to store the new - * string it is freed and reallocated. */ - if(tng_data->first_pgp_signature && strlen(tng_data->first_pgp_signature) < - len) - { - free(tng_data->first_pgp_signature); - tng_data->first_pgp_signature = 0; - } - if(!tng_data->first_pgp_signature) - { - tng_data->first_pgp_signature = malloc(len); - if(!tng_data->first_pgp_signature) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, - __FILE__, __LINE__); - return(TNG_CRITICAL); - } - } - - strncpy(tng_data->first_pgp_signature, signature, len); - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_last_signature_get - (const tng_trajectory_t tng_data, - char *signature, const int max_len) -{ - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(signature, "TNG library: signature must not be a NULL pointer"); - - strncpy(signature, tng_data->last_pgp_signature, max_len - 1); - signature[max_len - 1] = 0; - - if(strlen(tng_data->last_pgp_signature) > (unsigned int)max_len - 1) - { - return(TNG_FAILURE); - } - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_last_signature_set - (tng_trajectory_t tng_data, - const char *signature) -{ - unsigned int len; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(signature, "TNG library: signature must not be a NULL pointer"); - - len = tng_min_i((int)strlen(signature) + 1, TNG_MAX_STR_LEN); - - /* If the currently stored string length is not enough to store the new - * string it is freed and reallocated. */ - if(tng_data->last_pgp_signature && strlen(tng_data->last_pgp_signature) < - len) - { - free(tng_data->last_pgp_signature); - tng_data->last_pgp_signature = 0; - } - if(!tng_data->last_pgp_signature) - { - tng_data->last_pgp_signature = malloc(len); - if(!tng_data->last_pgp_signature) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, - __FILE__, __LINE__); - return(TNG_CRITICAL); - } - } - - strncpy(tng_data->last_pgp_signature, signature, len); - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_forcefield_name_get - (const tng_trajectory_t tng_data, - char *name, const int max_len) -{ - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer"); - - strncpy(name, tng_data->forcefield_name, max_len - 1); - name[max_len - 1] = 0; - - if(strlen(tng_data->forcefield_name) > (unsigned int)max_len - 1) - { - return(TNG_FAILURE); - } - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_forcefield_name_set - (tng_trajectory_t tng_data, - const char *new_name) -{ - unsigned int len; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(new_name, "TNG library: new_name must not be a NULL pointer"); - - len = tng_min_i((int)strlen(new_name) + 1, TNG_MAX_STR_LEN); - - /* If the currently stored string length is not enough to store the new - * string it is freed and reallocated. */ - if(tng_data->forcefield_name && strlen(tng_data->forcefield_name) < len) - { - free(tng_data->forcefield_name); - tng_data->forcefield_name = 0; - } - if(!tng_data->forcefield_name) - { - tng_data->forcefield_name = malloc(len); - if(!tng_data->forcefield_name) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", len, - __FILE__, __LINE__); - return(TNG_CRITICAL); - } - } - - strncpy(tng_data->forcefield_name, new_name, len); - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_medium_stride_length_get - (const tng_trajectory_t tng_data, - int64_t *len) -{ - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(len, "TNG library: len must not be a NULL pointer"); - - *len = tng_data->medium_stride_length; - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_medium_stride_length_set - (tng_trajectory_t tng_data, - const int64_t len) -{ - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - - if(len >= tng_data->long_stride_length) - { - return(TNG_FAILURE); - } - tng_data->medium_stride_length = len; - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_long_stride_length_get - (const tng_trajectory_t tng_data, - int64_t *len) -{ - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(len, "TNG library: len must not be a NULL pointer"); - - *len = tng_data->long_stride_length; - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_long_stride_length_set - (tng_trajectory_t tng_data, - const int64_t len) -{ - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - - if(len <= tng_data->medium_stride_length) - { - return(TNG_FAILURE); - } - tng_data->long_stride_length = len; + tng_data->long_stride_length = len; return(TNG_SUCCESS); } @@ -11245,7 +10185,7 @@ tng_function_status DECLSPECDLLEXPORT tng_time_per_frame_get } tng_function_status DECLSPECDLLEXPORT tng_time_per_frame_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const double time) { tng_trajectory_frame_set_t frame_set; @@ -11319,18 +10259,20 @@ tng_function_status DECLSPECDLLEXPORT tng_num_frames_get } tng_block_destroy(&block); - if(fread(&first_frame, sizeof(int64_t), 1, tng_data->input_file) == 0) + if(tng_file_input_numerical(tng_data, &first_frame, + sizeof(first_frame), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot read first frame of frame set. %s: %d\n", - __FILE__, __LINE__); return(TNG_CRITICAL); } - if(fread(&n_frames, sizeof(int64_t), 1, tng_data->input_file) == 0) + + if(tng_file_input_numerical(tng_data, &n_frames, + sizeof(n_frames), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot read n frames of frame set. %s: %d\n", - __FILE__, __LINE__); return(TNG_CRITICAL); } + fseeko(tng_data->input_file, file_pos, SEEK_SET); *n = first_frame + n_frames; @@ -11350,7 +10292,7 @@ tng_function_status DECLSPECDLLEXPORT tng_compression_precision_get } tng_function_status DECLSPECDLLEXPORT tng_compression_precision_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const double precision) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); @@ -11361,7 +10303,7 @@ tng_function_status DECLSPECDLLEXPORT tng_compression_precision_set } tng_function_status DECLSPECDLLEXPORT tng_implicit_num_particles_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t n) { tng_molecule_t mol; @@ -11582,9 +10524,15 @@ tng_function_status DECLSPECDLLEXPORT tng_num_frames_per_frame_set_set (const tng_trajectory_t tng_data, const int64_t n) { + tng_trajectory_frame_set_t frame_set; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); tng_data->frame_set_n_frames = n; + frame_set = &tng_data->current_trajectory_frame_set; + if(frame_set) + { + frame_set->n_frames = n; + } return(TNG_SUCCESS); } @@ -11619,8 +10567,8 @@ tng_function_status DECLSPECDLLEXPORT tng_num_frame_sets_get tng_block_init(&block); fseeko(tng_data->input_file, - file_pos, - SEEK_SET); + file_pos, + SEEK_SET); tng_data->current_trajectory_frame_set_input_file_pos = file_pos; /* Read block headers first to see what block is found. */ stat = tng_block_header_read(tng_data, block); @@ -11682,8 +10630,8 @@ tng_function_status DECLSPECDLLEXPORT tng_num_frame_sets_get { cnt += medium_stride_length; fseeko(tng_data->input_file, - file_pos, - SEEK_SET); + file_pos, + SEEK_SET); /* Read block headers first to see what block is found. */ stat = tng_block_header_read(tng_data, block); if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET) @@ -11712,8 +10660,8 @@ tng_function_status DECLSPECDLLEXPORT tng_num_frame_sets_get { ++cnt; fseeko(tng_data->input_file, - file_pos, - SEEK_SET); + file_pos, + SEEK_SET); /* Read block headers first to see what block is found. */ stat = tng_block_header_read(tng_data, block); if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET) @@ -11765,7 +10713,7 @@ tng_function_status DECLSPECDLLEXPORT tng_current_frame_set_get } tng_function_status DECLSPECDLLEXPORT tng_frame_set_nr_find - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t nr) { int64_t long_stride_length, medium_stride_length; @@ -12089,7 +11037,7 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_nr_find } tng_function_status DECLSPECDLLEXPORT tng_frame_set_of_frame_find - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame) { int64_t first_frame, last_frame, n_frames_per_frame_set; @@ -12504,3500 +11452,2421 @@ tng_function_status DECLSPECDLLEXPORT tng_frame_set_prev_frame_set_file_pos_get { (void)tng_data; - TNG_ASSERT(frame_set, "TNG library: frame_set not initialised before accessing data."); - TNG_ASSERT(pos, "TNG library: pos must not be a NULL pointer"); - - *pos = frame_set->prev_frame_set_file_pos; - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_frame_set_frame_range_get - (const tng_trajectory_t tng_data, - const tng_trajectory_frame_set_t frame_set, - int64_t *first_frame, - int64_t *last_frame) -{ - (void)tng_data; - - TNG_ASSERT(first_frame, "TNG library: first_frame must not be a NULL pointer"); - TNG_ASSERT(last_frame, "TNG library: last_frame must not be a NULL pointer"); - TNG_ASSERT(frame_set, "TNG library: frame_set must not be a NULL pointer"); - - *first_frame = frame_set->first_frame; - *last_frame = *first_frame + frame_set->n_frames - 1; - - return(TNG_SUCCESS); -} - -/** Translate from the particle numbering used in a frame set to the real - * particle numbering - used in the molecule description. - * @param frame_set is the frame_set containing the mappings to use. - * @param local is the index number of the atom in this frame set - * @param real is set to the index of the atom in the molecular system. - * @return TNG_SUCCESS (0) if successful or TNG_FAILURE (1) if the mapping - * cannot be found. - */ -static TNG_INLINE tng_function_status tng_particle_mapping_get_real_particle - (const tng_trajectory_frame_set_t frame_set, - const int64_t local, - int64_t *real) -{ - int64_t i, n_blocks = frame_set->n_mapping_blocks, first; - tng_particle_mapping_t mapping; - if(n_blocks <= 0) - { - *real = local; - return(TNG_SUCCESS); - } - for(i = 0; i < n_blocks; i++) - { - mapping = &frame_set->mappings[i]; - first = mapping->num_first_particle; - if(local < first || - local >= first + mapping->n_particles) - { - continue; - } - *real = mapping->real_particle_numbers[local-first]; - return(TNG_SUCCESS); - } - *real = local; - return(TNG_FAILURE); -} - -/** Translate from the real particle numbering to the particle numbering - * used in a frame set. - * @param frame_set is the frame_set containing the mappings to use. - * @param real is the index number of the atom in the molecular system. - * @param local is set to the index of the atom in this frame set. - * @return TNG_SUCCESS (0) if successful or TNG_FAILURE (1) if the mapping - * cannot be found. - */ -/*static TNG_INLINE tng_function_status tng_particle_mapping_get_local_particle - (const tng_trajectory_frame_set_t frame_set, - const int64_t real, - int64_t *local) -{ - int64_t i, j, n_blocks = frame_set->n_mapping_blocks; - tng_particle_mapping_t mapping; - if(n_blocks <= 0) - { - *local = real; - return(TNG_SUCCESS); - } - for(i = 0; i < n_blocks; i++) - { - mapping = &frame_set->mappings[i]; - for(j = mapping->n_particles; j--;) - { - if(mapping->real_particle_numbers[j] == real) - { - *local = j; - return(TNG_SUCCESS); - } - } - } - return(TNG_FAILURE); -} -*/ - -static tng_function_status tng_file_headers_len_get - (tng_trajectory_t tng_data, - int64_t *len) -{ - int64_t orig_pos; - tng_gen_block_t block; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - - if(tng_input_file_init(tng_data) != TNG_SUCCESS) - { - return(TNG_CRITICAL); - } - - *len = 0; - - orig_pos = ftello(tng_data->input_file); - - if(!tng_data->input_file_len) - { - fseeko(tng_data->input_file, 0, SEEK_END); - tng_data->input_file_len = ftello(tng_data->input_file); - } - fseeko(tng_data->input_file, 0, SEEK_SET); - - tng_block_init(&block); - /* Read through the headers of non-trajectory blocks (they come before the - * trajectory blocks in the file) */ - while (*len < tng_data->input_file_len && - tng_block_header_read(tng_data, block) != TNG_CRITICAL && - block->id != -1 && - block->id != TNG_TRAJECTORY_FRAME_SET) - { - *len += block->header_contents_size + block->block_contents_size; - fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR); - } - - fseeko(tng_data->input_file, orig_pos, SEEK_SET); - - tng_block_destroy(&block); - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_file_headers_read - (tng_trajectory_t tng_data, - const char hash_mode) -{ - int64_t prev_pos = 0; - tng_gen_block_t block; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - - tng_data->n_trajectory_frame_sets = 0; - - if(tng_input_file_init(tng_data) != TNG_SUCCESS) - { - return(TNG_CRITICAL); - } - - if(!tng_data->input_file_len) - { - fseeko(tng_data->input_file, 0, SEEK_END); - tng_data->input_file_len = ftello(tng_data->input_file); - } - fseeko(tng_data->input_file, 0, SEEK_SET); - - tng_block_init(&block); - /* Non trajectory blocks (they come before the trajectory - * blocks in the file) */ - while (prev_pos < tng_data->input_file_len && - tng_block_header_read(tng_data, block) != TNG_CRITICAL && - block->id != -1 && - block->id != TNG_TRAJECTORY_FRAME_SET) - { - tng_block_read_next(tng_data, block, hash_mode); - prev_pos = ftello(tng_data->input_file); - } - - /* Go back if a trajectory block was encountered */ - if(block->id == TNG_TRAJECTORY_FRAME_SET) - { - fseeko(tng_data->input_file, prev_pos, SEEK_SET); - } - - tng_block_destroy(&block); - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_file_headers_write - (tng_trajectory_t tng_data, - const char hash_mode) -{ - int i; - int64_t len, orig_len, tot_len = 0, data_start_pos; - tng_function_status stat; - tng_gen_block_t block; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - - if(tng_output_file_init(tng_data) != TNG_SUCCESS) - { - return(TNG_CRITICAL); - } - - if(tng_data->n_trajectory_frame_sets > 0) - { - stat = tng_file_headers_len_get(tng_data, &orig_len); - if(stat != TNG_SUCCESS) - { - return(stat); - } - - tng_block_init(&block); - block->name = malloc(TNG_MAX_STR_LEN); - if(!block->name) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", - TNG_MAX_STR_LEN, __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); - } - strcpy(block->name, "GENERAL INFO"); - tng_block_header_len_calculate(tng_data, block, &len); - tot_len += len; - tng_general_info_block_len_calculate(tng_data, &len); - tot_len += len; - strcpy(block->name, "MOLECULES"); - tng_block_header_len_calculate(tng_data, block, &len); - tot_len += len; - tng_molecules_block_len_calculate(tng_data, &len); - tot_len += len; - - for(i = 0; i < tng_data->n_data_blocks; i++) - { - strcpy(block->name, tng_data->non_tr_data[i].block_name); - tng_block_header_len_calculate(tng_data, block, &len); - tot_len += len; - tng_data_block_len_calculate(tng_data, - (tng_particle_data_t)&tng_data->non_tr_data[i], - TNG_FALSE, 1, 1, 1, 0, - 1, 0, &data_start_pos, - &len); - tot_len += len; - } - for(i = 0; i < tng_data->n_particle_data_blocks; i++) - { - strcpy(block->name, tng_data->non_tr_particle_data[i].block_name); - tng_block_header_len_calculate(tng_data, block, &len); - tot_len += len; - tng_data_block_len_calculate(tng_data, - &tng_data->non_tr_particle_data[i], - TNG_TRUE, 1, 1, 1, 0, - tng_data->n_particles, TNG_PARTICLE_DEPENDENT, - &data_start_pos, - &len); - tot_len += len; - } - tng_block_destroy(&block); - - if(tot_len > orig_len) - { - tng_migrate_data_in_file(tng_data, orig_len+1, tot_len - orig_len); - } - - tng_data->current_trajectory_frame_set_output_file_pos = -1; - } - - /* TODO: If there is already frame set data written to this file (e.g. when - * appending to an already existing file we might need to move frame sets to - * the end of the file. */ - - if(tng_general_info_block_write(tng_data, hash_mode) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Error writing general info block of file %s. %s: %d\n", - tng_data->input_file_path, __FILE__, __LINE__); - return(TNG_CRITICAL); - } - - if(tng_molecules_block_write(tng_data, hash_mode) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Error writing atom names block of file %s. %s: %d\n", - tng_data->input_file_path, __FILE__, __LINE__); - return(TNG_CRITICAL); - } - - /* FIXME: Currently writing non-trajectory data blocks here. - * Should perhaps be moved. */ - tng_block_init(&block); - for(i = 0; i < tng_data->n_data_blocks; i++) - { - block->id = tng_data->non_tr_data[i].block_id; - tng_data_block_write(tng_data, block, - i, hash_mode); - } - - for(i = 0; i < tng_data->n_particle_data_blocks; i++) - { - block->id = tng_data->non_tr_particle_data[i].block_id; - tng_particle_data_block_write(tng_data, block, - i, 0, hash_mode); - } - - tng_block_destroy(&block); - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_block_read_next(tng_trajectory_t tng_data, - tng_gen_block_t block, - const char hash_mode) -{ - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(block, "TNG library: block must be initialised and must not be a NULL pointer."); - - switch(block->id) - { - case TNG_TRAJECTORY_FRAME_SET: - return(tng_frame_set_block_read(tng_data, block, hash_mode)); - case TNG_PARTICLE_MAPPING: - return(tng_trajectory_mapping_block_read(tng_data, block, hash_mode)); - case TNG_GENERAL_INFO: - return(tng_general_info_block_read(tng_data, block, hash_mode)); - case TNG_MOLECULES: - return(tng_molecules_block_read(tng_data, block, hash_mode)); - default: - if(block->id >= TNG_TRAJ_BOX_SHAPE) - { - return(tng_data_block_contents_read(tng_data, block, hash_mode)); - } - else - { - /* Skip to the next block */ - fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR); - return(TNG_FAILURE); - } - } -} - -tng_function_status DECLSPECDLLEXPORT tng_frame_set_read - (tng_trajectory_t tng_data, - const char hash_mode) -{ - int64_t file_pos; - tng_gen_block_t block; - tng_function_status stat; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - - if(tng_input_file_init(tng_data) != TNG_SUCCESS) - { - return(TNG_CRITICAL); - } - - file_pos = ftello(tng_data->input_file); - - tng_block_init(&block); - - if(!tng_data->input_file_len) - { - fseeko(tng_data->input_file, 0, SEEK_END); - tng_data->input_file_len = ftello(tng_data->input_file); - fseeko(tng_data->input_file, file_pos, SEEK_SET); - } - - /* Read block headers first to see what block is found. */ - stat = tng_block_header_read(tng_data, block); - if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET || - block->id == -1) - { - fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", - file_pos, __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); - } - - tng_data->current_trajectory_frame_set_input_file_pos = file_pos; - - if(tng_block_read_next(tng_data, block, - hash_mode) == TNG_SUCCESS) - { - tng_data->n_trajectory_frame_sets++; - file_pos = ftello(tng_data->input_file); - /* Read all blocks until next frame set block */ - stat = tng_block_header_read(tng_data, block); - while(file_pos < tng_data->input_file_len && - stat != TNG_CRITICAL && - block->id != TNG_TRAJECTORY_FRAME_SET && - block->id != -1) - { - stat = tng_block_read_next(tng_data, block, - hash_mode); - if(stat != TNG_CRITICAL) - { - file_pos = ftello(tng_data->input_file); - if(file_pos < tng_data->input_file_len) - { - stat = tng_block_header_read(tng_data, block); - } - } - } - if(stat == TNG_CRITICAL) - { - fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", - file_pos, __FILE__, __LINE__); - tng_block_destroy(&block); - return(stat); - } - - if(block->id == TNG_TRAJECTORY_FRAME_SET) - { - fseeko(tng_data->input_file, file_pos, SEEK_SET); - } - } - - tng_block_destroy(&block); - - return(TNG_SUCCESS); -} - - -tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_current_only_data_from_block_id - (tng_trajectory_t tng_data, - const char hash_mode, - const int64_t block_id) -{ - int64_t file_pos; - tng_gen_block_t block; - tng_function_status stat; - int found_flag = 1; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - - if(tng_input_file_init(tng_data) != TNG_SUCCESS) - { - return(TNG_CRITICAL); - } - - file_pos = tng_data->current_trajectory_frame_set_input_file_pos; - - if(file_pos < 0) - { - /* No current frame set. This means that the first frame set must be - * read */ - found_flag = 0; - file_pos = tng_data->first_trajectory_frame_set_input_file_pos; - } - - if(file_pos > 0) - { - fseeko(tng_data->input_file, - file_pos, - SEEK_SET); - } - else - { - return(TNG_FAILURE); - } - - tng_block_init(&block); - - if(!tng_data->input_file_len) - { - fseeko(tng_data->input_file, 0, SEEK_END); - tng_data->input_file_len = ftello(tng_data->input_file); - fseeko(tng_data->input_file, file_pos, SEEK_SET); - } - - /* Read block headers first to see what block is found. */ - stat = tng_block_header_read(tng_data, block); - if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET) - { - fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", - file_pos, __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); - } - /* If the current frame set had already been read skip its block contents */ - if(found_flag) - { - fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR); - } - /* Otherwiese read the frame set block */ - else - { - stat = tng_block_read_next(tng_data, block, - hash_mode); - if(stat != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot read frame set block. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); - return(stat); - } - } - file_pos = ftello(tng_data->input_file); - - found_flag = 0; - - /* Read only blocks of the requested ID - * until next frame set block */ - stat = tng_block_header_read(tng_data, block); - while(file_pos < tng_data->input_file_len && - stat != TNG_CRITICAL && - block->id != TNG_TRAJECTORY_FRAME_SET && - block->id != -1) - { - if(block->id == block_id) - { - stat = tng_block_read_next(tng_data, block, - hash_mode); - if(stat != TNG_CRITICAL) - { - file_pos = ftello(tng_data->input_file); - found_flag = 1; - if(file_pos < tng_data->input_file_len) - { - stat = tng_block_header_read(tng_data, block); - } - } - } - else - { - file_pos += (block->block_contents_size + block->header_contents_size); - fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR); - if(file_pos < tng_data->input_file_len) - { - stat = tng_block_header_read(tng_data, block); - } - } - } - if(stat == TNG_CRITICAL) - { - fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", - file_pos, __FILE__, __LINE__); - tng_block_destroy(&block); - return(stat); - } - - if(block->id == TNG_TRAJECTORY_FRAME_SET) - { - fseeko(tng_data->input_file, file_pos, SEEK_SET); - } - - tng_block_destroy(&block); - - if(found_flag) - { - return(TNG_SUCCESS); - } - else - { - return(TNG_FAILURE); - } -} - -tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_next - (tng_trajectory_t tng_data, - const char hash_mode) -{ - int64_t file_pos; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - - if(tng_input_file_init(tng_data) != TNG_SUCCESS) - { - return(TNG_CRITICAL); - } - - file_pos = tng_data->current_trajectory_frame_set.next_frame_set_file_pos; - - if(file_pos < 0 && tng_data->current_trajectory_frame_set_input_file_pos <= 0) - { - file_pos = tng_data->first_trajectory_frame_set_input_file_pos; - } - - if(file_pos > 0) - { - fseeko(tng_data->input_file, - file_pos, - SEEK_SET); - } - else - { - return(TNG_FAILURE); - } - - return(tng_frame_set_read(tng_data, hash_mode)); -} - -tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_next_only_data_from_block_id - (tng_trajectory_t tng_data, - const char hash_mode, - const int64_t block_id) -{ - int64_t file_pos; - tng_gen_block_t block; - tng_function_status stat; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - - if(tng_input_file_init(tng_data) != TNG_SUCCESS) - { - return(TNG_CRITICAL); - } - - file_pos = tng_data->current_trajectory_frame_set.next_frame_set_file_pos; - - if(file_pos < 0 && tng_data->current_trajectory_frame_set_input_file_pos <= 0) - { - file_pos = tng_data->first_trajectory_frame_set_input_file_pos; - } - - if(file_pos > 0) - { - fseeko(tng_data->input_file, - file_pos, - SEEK_SET); - } - else - { - return(TNG_FAILURE); - } - - tng_block_init(&block); - - if(!tng_data->input_file_len) - { - fseeko(tng_data->input_file, 0, SEEK_END); - tng_data->input_file_len = ftello(tng_data->input_file); - fseeko(tng_data->input_file, file_pos, SEEK_SET); - } - - /* Read block headers first to see what block is found. */ - stat = tng_block_header_read(tng_data, block); - if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET) - { - fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", - file_pos, __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); - } - - tng_data->current_trajectory_frame_set_input_file_pos = file_pos; - - if(tng_block_read_next(tng_data, block, - hash_mode) == TNG_SUCCESS) - { - stat = tng_frame_set_read_current_only_data_from_block_id(tng_data, hash_mode, block_id); - } - - tng_block_destroy(&block); - - return(stat); -} - -tng_function_status tng_frame_set_write(tng_trajectory_t tng_data, - const char hash_mode) -{ - int i, j; - tng_gen_block_t block; - tng_trajectory_frame_set_t frame_set; - tng_function_status stat; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - - frame_set = &tng_data->current_trajectory_frame_set; - - if(frame_set->n_written_frames == frame_set->n_frames) - { - return(TNG_SUCCESS); - } - - tng_data->current_trajectory_frame_set_output_file_pos = - ftello(tng_data->output_file); - tng_data->last_trajectory_frame_set_output_file_pos = - tng_data->current_trajectory_frame_set_output_file_pos; - - if(tng_data->current_trajectory_frame_set_output_file_pos <= 0) - { - return(TNG_FAILURE); - } - - if(tng_data->first_trajectory_frame_set_output_file_pos == -1) - { - tng_data->first_trajectory_frame_set_output_file_pos = - tng_data->current_trajectory_frame_set_output_file_pos; - } - - tng_block_init(&block); - - if(tng_frame_set_block_write(tng_data, block, hash_mode) != TNG_SUCCESS) - { - tng_block_destroy(&block); - return(TNG_FAILURE); - } - - /* Write non-particle data blocks */ - for(i = 0; in_data_blocks; i++) - { - block->id = frame_set->tr_data[i].block_id; - tng_data_block_write(tng_data, block, i, hash_mode); - } - /* Write the mapping blocks and particle data blocks*/ - if(frame_set->n_mapping_blocks) - { - for(i = 0; i < frame_set->n_mapping_blocks; i++) - { - block->id = TNG_PARTICLE_MAPPING; - if(frame_set->mappings[i].n_particles > 0) - { - tng_trajectory_mapping_block_write(tng_data, block, i, hash_mode); - for(j = 0; jn_particle_data_blocks; j++) - { - block->id = frame_set->tr_particle_data[j].block_id; - tng_particle_data_block_write(tng_data, block, - j, &frame_set->mappings[i], - hash_mode); - } - } - } - } - else - { - for(i = 0; in_particle_data_blocks; i++) - { - block->id = frame_set->tr_particle_data[i].block_id; - tng_particle_data_block_write(tng_data, block, - i, 0, hash_mode); - } - } - - - /* Update pointers in the general info block */ - stat = tng_header_pointers_update(tng_data, hash_mode); - - if(stat == TNG_SUCCESS) - { - stat = tng_frame_set_pointers_update(tng_data, hash_mode); - } - - tng_block_destroy(&block); - - 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, - const int64_t n_frames) -{ - tng_gen_block_t block; - tng_trajectory_frame_set_t frame_set; - FILE *temp = tng_data->input_file; - int64_t curr_pos; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(first_frame >= 0, "TNG library: first_frame must be >= 0."); - TNG_ASSERT(n_frames >= 0, "TNG library: n_frames must be >= 0."); - - frame_set = &tng_data->current_trajectory_frame_set; - - curr_pos = ftello(tng_data->output_file); - - if(curr_pos <= 10) - { - tng_file_headers_write(tng_data, TNG_USE_HASH); - } - - /* Set pointer to previous frame set to the one that was loaded - * before. - * FIXME: This is a bit risky. If they are not added in order - * it will be wrong. */ - if(tng_data->n_trajectory_frame_sets) - { - frame_set->prev_frame_set_file_pos = - tng_data->current_trajectory_frame_set_output_file_pos; - } - - tng_data->current_trajectory_frame_set_output_file_pos = - ftello(tng_data->output_file); - - tng_data->n_trajectory_frame_sets++; - - /* Set the medium range pointers */ - if(tng_data->n_trajectory_frame_sets == tng_data->medium_stride_length + 1) - { - frame_set->medium_stride_prev_frame_set_file_pos = - tng_data->first_trajectory_frame_set_output_file_pos; - } - else if(tng_data->n_trajectory_frame_sets > tng_data->medium_stride_length + 1) - { - /* FIXME: Currently only working if the previous frame set has its - * medium stride pointer already set. This might need some fixing. */ - if(frame_set->medium_stride_prev_frame_set_file_pos != -1 && - frame_set->medium_stride_prev_frame_set_file_pos != 0) - { - tng_block_init(&block); - tng_data->input_file = tng_data->output_file; - - curr_pos = ftello(tng_data->output_file); - fseeko(tng_data->output_file, - frame_set->medium_stride_prev_frame_set_file_pos, - SEEK_SET); - - if(tng_block_header_read(tng_data, block) != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot read frame set header. %s: %d\n", - __FILE__, __LINE__); - tng_data->input_file = temp; - tng_block_destroy(&block); - return(TNG_CRITICAL); - } - - /* Read the next frame set from the previous frame set and one - * medium stride step back */ - fseeko(tng_data->output_file, block->block_contents_size - (6 * - sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR); - if(fread(&frame_set->medium_stride_prev_frame_set_file_pos, - sizeof(frame_set->medium_stride_prev_frame_set_file_pos), - 1, tng_data->output_file) == 0) - { - fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, __LINE__); - tng_data->input_file = temp; - tng_block_destroy(&block); - return(TNG_CRITICAL); - } - - if(tng_data->input_endianness_swap_func_64) - { - if(tng_data->input_endianness_swap_func_64(tng_data, - &frame_set->medium_stride_prev_frame_set_file_pos) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - - tng_block_destroy(&block); - - /* Set the long range pointers */ - if(tng_data->n_trajectory_frame_sets == tng_data->long_stride_length + 1) - { - frame_set->long_stride_prev_frame_set_file_pos = - tng_data->first_trajectory_frame_set_output_file_pos; - } - else if(tng_data->n_trajectory_frame_sets > tng_data->medium_stride_length + 1) - { - /* FIXME: Currently only working if the previous frame set has its - * long stride pointer already set. This might need some fixing. */ - if(frame_set->long_stride_prev_frame_set_file_pos != -1 && - frame_set->long_stride_prev_frame_set_file_pos != 0) - { - tng_block_init(&block); - tng_data->input_file = tng_data->output_file; - - fseeko(tng_data->output_file, - frame_set->long_stride_prev_frame_set_file_pos, - SEEK_SET); - - if(tng_block_header_read(tng_data, block) != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot read frame set header. %s: %d\n", - __FILE__, __LINE__); - tng_data->input_file = temp; - tng_block_destroy(&block); - return(TNG_CRITICAL); - } - - /* Read the next frame set from the previous frame set and one - * long stride step back */ - fseeko(tng_data->output_file, block->block_contents_size - (6 * - sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR); - - tng_block_destroy(&block); - - if(fread(&frame_set->long_stride_prev_frame_set_file_pos, - sizeof(frame_set->long_stride_prev_frame_set_file_pos), - 1, tng_data->output_file) == 0) - { - fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, __LINE__); - tng_data->input_file = temp; - return(TNG_CRITICAL); - } - - if(tng_data->input_endianness_swap_func_64) - { - if(tng_data->input_endianness_swap_func_64(tng_data, - &frame_set->long_stride_prev_frame_set_file_pos) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - - } - } - - tng_data->input_file = temp; - fseeko(tng_data->output_file, curr_pos, SEEK_SET); - } - } - - frame_set->first_frame = first_frame; - frame_set->n_frames = n_frames; - frame_set->n_written_frames = 0; - frame_set->n_unwritten_frames = 0; - frame_set->first_frame_time = -1; - - if(tng_data->first_trajectory_frame_set_output_file_pos == -1 || - tng_data->first_trajectory_frame_set_output_file_pos == 0) - { - tng_data->first_trajectory_frame_set_output_file_pos = - tng_data->current_trajectory_frame_set_output_file_pos; - } - /* FIXME: Should check the frame number instead of the file_pos, - * in case frame sets are not in order */ - if(tng_data->last_trajectory_frame_set_output_file_pos == -1 || - tng_data->last_trajectory_frame_set_output_file_pos == 0 || - tng_data->last_trajectory_frame_set_output_file_pos < - tng_data->current_trajectory_frame_set_output_file_pos) - { - tng_data->last_trajectory_frame_set_output_file_pos = - tng_data->current_trajectory_frame_set_output_file_pos; - } - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_frame_set_with_time_new - (tng_trajectory_t tng_data, - const int64_t first_frame, - const int64_t n_frames, - const double first_frame_time) -{ - tng_function_status stat; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(first_frame >= 0, "TNG library: first_frame must be >= 0."); - TNG_ASSERT(n_frames >= 0, "TNG library: n_frames must be >= 0."); - TNG_ASSERT(first_frame_time >= 0, "TNG library: first_frame_time must be >= 0."); - - - stat = tng_frame_set_new(tng_data, first_frame, n_frames); - if(stat != TNG_SUCCESS) - { - return(stat); - } - stat = tng_frame_set_first_frame_time_set(tng_data, first_frame_time); - - return(stat); -} - -tng_function_status DECLSPECDLLEXPORT tng_frame_set_first_frame_time_set - (tng_trajectory_t tng_data, - const double first_frame_time) -{ - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(first_frame_time >= 0, "TNG library: first_frame_time must be >= 0."); - - tng_data->current_trajectory_frame_set.first_frame_time = first_frame_time; - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_first_frame_nr_of_next_frame_set_get - (const tng_trajectory_t tng_data, - int64_t *frame) -{ - int64_t file_pos, next_frame_set_file_pos; - tng_gen_block_t block; - tng_function_status stat; - - tng_trajectory_frame_set_t frame_set; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(tng_data->input_file, "TNG library: An input file must be open to find the next frame set"); - TNG_ASSERT(frame, "TNG library: frame must not be a NULL pointer"); - - file_pos = ftello(tng_data->input_file); - - if(tng_data->current_trajectory_frame_set_input_file_pos <= 0) - { - next_frame_set_file_pos = tng_data->first_trajectory_frame_set_input_file_pos; - } - else - { - frame_set = &tng_data->current_trajectory_frame_set; - next_frame_set_file_pos = frame_set->next_frame_set_file_pos; - } - - if(next_frame_set_file_pos <= 0) - { - return(TNG_FAILURE); - } - - fseeko(tng_data->input_file, next_frame_set_file_pos, SEEK_SET); - /* Read block headers first to see that a frame set block is found. */ - tng_block_init(&block); - stat = tng_block_header_read(tng_data, block); - if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET) - { - fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", - file_pos, __FILE__, __LINE__); - return(TNG_CRITICAL); - } -/* if(tng_data->current_trajectory_frame_set_input_file_pos <= 0) - { - tng_block_read_next(tng_data, block, TNG_USE_HASH); - }*/ - tng_block_destroy(&block); - - if(fread(frame, sizeof(int64_t), 1, tng_data->input_file) == 0) - { - fprintf(stderr, "TNG library: Cannot read first frame of next frame set. %s: %d\n", - __FILE__, __LINE__); - return(TNG_CRITICAL); - } - fseeko(tng_data->input_file, file_pos, SEEK_SET); - - return(TNG_SUCCESS); -} - -tng_function_status DECLSPECDLLEXPORT tng_data_block_add - (tng_trajectory_t tng_data, - const int64_t id, - const char *block_name, - const char datatype, - const char block_type_flag, - int64_t n_frames, - const int64_t n_values_per_frame, - int64_t stride_length, - const int64_t codec_id, - void *new_data) -{ - int i, j, size, len; - tng_trajectory_frame_set_t frame_set; - tng_non_particle_data_t data; - char **first_dim_values; - char *new_data_c=new_data; - int64_t n_frames_div; - - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(block_name, "TNG library: block_name must not be a NULL pointer."); - TNG_ASSERT(n_values_per_frame > 0, "TNG library: n_values_per_frame must be a positive integer."); - - frame_set = &tng_data->current_trajectory_frame_set; - - if(stride_length <= 0) - { - stride_length = 1; - } - - /* If the block does not exist, create it */ - if(tng_data_find(tng_data, id, &data) != TNG_SUCCESS) - { - if(tng_data_block_create(tng_data, block_type_flag) != - TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot create data block. %s: %d\n", - __FILE__, __LINE__); - return(TNG_CRITICAL); - } - if(block_type_flag == TNG_TRAJECTORY_BLOCK) - { - data = &frame_set->tr_data[frame_set->n_data_blocks - 1]; - } - else - { - data = &tng_data->non_tr_data[tng_data->n_data_blocks - 1]; - } - data->block_id = id; - - data->block_name = malloc(strlen(block_name) + 1); - if(!data->block_name) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", - (int)strlen(block_name)+1, __FILE__, __LINE__); - return(TNG_CRITICAL); - } - strncpy(data->block_name, block_name, strlen(block_name) + 1); - - data->values = 0; - /* FIXME: Memory leak from strings. */ - data->strings = 0; - data->last_retrieved_frame = -1; - } - - data->datatype = datatype; - data->stride_length = tng_max_i64(stride_length, 1); - data->n_values_per_frame = n_values_per_frame; - data->n_frames = n_frames; - data->codec_id = codec_id; - data->compression_multiplier = 1.0; - /* FIXME: This can cause problems. */ - data->first_frame_with_data = frame_set->first_frame; - - switch(datatype) - { - case TNG_FLOAT_DATA: - size = sizeof(float); - break; - case TNG_INT_DATA: - size = sizeof(int64_t); - break; - case TNG_DOUBLE_DATA: - default: - size = sizeof(double); - break; - } - - if(new_data_c) - { - /* Allocate memory */ - if(tng_allocate_data_mem(tng_data, data, n_frames, stride_length, - n_values_per_frame) != - TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot allocate data memory. %s: %d\n", - __FILE__, __LINE__); - return(TNG_CRITICAL); - } - - if(n_frames > frame_set->n_unwritten_frames) - { - frame_set->n_unwritten_frames = n_frames; - } - - n_frames_div = (n_frames % stride_length) ? - n_frames / stride_length + 1: - n_frames / stride_length; + TNG_ASSERT(frame_set, "TNG library: frame_set not initialised before accessing data."); + TNG_ASSERT(pos, "TNG library: pos must not be a NULL pointer"); - if(datatype == TNG_CHAR_DATA) - { - for(i = 0; i < n_frames_div; i++) - { - first_dim_values = data->strings[i]; - for(j = 0; j < n_values_per_frame; j++) - { - len = tng_min_i((int)strlen(new_data_c) + 1, - TNG_MAX_STR_LEN); - if(first_dim_values[j]) - { - free(first_dim_values[j]); - } - first_dim_values[j] = malloc(len); - if(!first_dim_values[j]) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", - len, __FILE__, __LINE__); - return(TNG_CRITICAL); - } - strncpy(first_dim_values[j], - new_data_c, len); - new_data_c += len; - } - } - } - else - { - memcpy(data->values, new_data, size * n_frames_div * - n_values_per_frame); - } - } + *pos = frame_set->prev_frame_set_file_pos; return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_particle_data_block_add - (tng_trajectory_t tng_data, - const int64_t id, - const char *block_name, - const char datatype, - const char block_type_flag, - int64_t n_frames, - const int64_t n_values_per_frame, - int64_t stride_length, - const int64_t num_first_particle, - const int64_t n_particles, - const int64_t codec_id, - void *new_data) +tng_function_status DECLSPECDLLEXPORT tng_frame_set_frame_range_get + (const tng_trajectory_t tng_data, + const tng_trajectory_frame_set_t frame_set, + int64_t *first_frame, + int64_t *last_frame) { - int i, size, len; - int64_t j, k; - int64_t tot_n_particles, n_frames_div; - char ***first_dim_values, **second_dim_values; - tng_trajectory_frame_set_t frame_set; - tng_particle_data_t data; - char *new_data_c=new_data; + (void)tng_data; - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(block_name, "TNG library: block_name mustnot be a NULL pointer."); - TNG_ASSERT(n_values_per_frame > 0, "TNG library: n_values_per_frame must be a positive integer."); - TNG_ASSERT(num_first_particle >= 0, "TNG library: num_first_particle must be >= 0."); - TNG_ASSERT(n_particles >= 0, "TNG library: n_particles must be >= 0."); + TNG_ASSERT(first_frame, "TNG library: first_frame must not be a NULL pointer"); + TNG_ASSERT(last_frame, "TNG library: last_frame must not be a NULL pointer"); + TNG_ASSERT(frame_set, "TNG library: frame_set must not be a NULL pointer"); + *first_frame = frame_set->first_frame; + *last_frame = *first_frame + frame_set->n_frames - 1; - frame_set = &tng_data->current_trajectory_frame_set; + return(TNG_SUCCESS); +} - if(stride_length <= 0) +/** + * @brief Translate from the particle numbering used in a frame set to the real + * particle numbering - used in the molecule description. + * @param frame_set is the frame_set containing the mappings to use. + * @param local is the index number of the atom in this frame set + * @param real is set to the index of the atom in the molecular system. + * @return TNG_SUCCESS (0) if successful or TNG_FAILURE (1) if the mapping + * cannot be found. + */ +static TNG_INLINE tng_function_status tng_particle_mapping_get_real_particle + (const tng_trajectory_frame_set_t frame_set, + const int64_t local, + int64_t *real) +{ + int64_t i, n_blocks = frame_set->n_mapping_blocks, first; + tng_particle_mapping_t mapping; + if(n_blocks <= 0) { - stride_length = 1; + *real = local; + return(TNG_SUCCESS); } - - /* If the block does not exist, create it */ - if(tng_particle_data_find(tng_data, id, &data) != TNG_SUCCESS) + for(i = 0; i < n_blocks; i++) { - if(tng_particle_data_block_create(tng_data, block_type_flag) != - TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot create particle data block. %s: %d\n", - __FILE__, __LINE__); - return(TNG_CRITICAL); - } - if(block_type_flag == TNG_TRAJECTORY_BLOCK) - { - data = &frame_set->tr_particle_data[frame_set-> - n_particle_data_blocks - 1]; - } - else + mapping = &frame_set->mappings[i]; + first = mapping->num_first_particle; + if(local < first || + local >= first + mapping->n_particles) { - data = &tng_data->non_tr_particle_data[tng_data-> - n_particle_data_blocks - 1]; + continue; } - data->block_id = id; + *real = mapping->real_particle_numbers[local-first]; + return(TNG_SUCCESS); + } + *real = local; + return(TNG_FAILURE); +} - data->block_name = malloc(strlen(block_name) + 1); - if(!data->block_name) +/** + * @brief Translate from the real particle numbering to the particle numbering + * used in a frame set. + * @param frame_set is the frame_set containing the mappings to use. + * @param real is the index number of the atom in the molecular system. + * @param local is set to the index of the atom in this frame set. + * @return TNG_SUCCESS (0) if successful or TNG_FAILURE (1) if the mapping + * cannot be found. + */ +/*static TNG_INLINE tng_function_status tng_particle_mapping_get_local_particle + (const tng_trajectory_frame_set_t frame_set, + const int64_t real, + int64_t *local) +{ + int64_t i, j, n_blocks = frame_set->n_mapping_blocks; + tng_particle_mapping_t mapping; + if(n_blocks <= 0) + { + *local = real; + return(TNG_SUCCESS); + } + for(i = 0; i < n_blocks; i++) + { + mapping = &frame_set->mappings[i]; + for(j = mapping->n_particles; j--;) { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", - (int)strlen(block_name)+1, __FILE__, __LINE__); - return(TNG_CRITICAL); + if(mapping->real_particle_numbers[j] == real) + { + *local = j; + return(TNG_SUCCESS); + } } - strncpy(data->block_name, block_name, strlen(block_name) + 1); - - data->datatype = datatype; - - data->values = 0; - /* FIXME: Memory leak from strings. */ - data->strings = 0; - data->last_retrieved_frame = -1; } + return(TNG_FAILURE); +} +*/ - data->stride_length = tng_max_i64(stride_length, 1); - data->n_values_per_frame = n_values_per_frame; - data->n_frames = n_frames; - data->codec_id = codec_id; - data->compression_multiplier = 1.0; - /* FIXME: This can cause problems. */ - data->first_frame_with_data = frame_set->first_frame; +static tng_function_status tng_file_headers_len_get + (const tng_trajectory_t tng_data, + int64_t *len) +{ + int64_t orig_pos; + tng_gen_block_t block; + + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - if(block_type_flag == TNG_TRAJECTORY_BLOCK && tng_data->var_num_atoms_flag) + if(tng_input_file_init(tng_data) != TNG_SUCCESS) { - tot_n_particles = frame_set->n_particles; + return(TNG_CRITICAL); } - else + + *len = 0; + + orig_pos = ftello(tng_data->input_file); + + fseeko(tng_data->input_file, 0, SEEK_SET); + + tng_block_init(&block); + /* Read through the headers of non-trajectory blocks (they come before the + * trajectory blocks in the file) */ + while (*len < tng_data->input_file_len && + tng_block_header_read(tng_data, block) != TNG_CRITICAL && + block->id != -1 && + block->id != TNG_TRAJECTORY_FRAME_SET) { - tot_n_particles = tng_data->n_particles; + *len += block->header_contents_size + block->block_contents_size; + fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR); } - /* If data values are supplied add that data to the data block. */ - if(new_data_c) - { - /* Allocate memory */ - if(tng_allocate_particle_data_mem(tng_data, data, n_frames, - stride_length, tot_n_particles, - n_values_per_frame) != - TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot allocate particle data memory. %s: %d\n", - __FILE__, __LINE__); - return(TNG_CRITICAL); - } + fseeko(tng_data->input_file, orig_pos, SEEK_SET); - if(n_frames > frame_set->n_unwritten_frames) - { - frame_set->n_unwritten_frames = n_frames; - } + tng_block_destroy(&block); - n_frames_div = (n_frames % stride_length) ? - n_frames / stride_length + 1: - n_frames / stride_length; + return(TNG_SUCCESS); +} - if(datatype == TNG_CHAR_DATA) - { - for(i = 0; i < n_frames_div; i++) - { - first_dim_values = data->strings[i]; - for(j = num_first_particle; j < num_first_particle + n_particles; - j++) - { - second_dim_values = first_dim_values[j]; - for(k = 0; k < n_values_per_frame; k++) - { - len = tng_min_i((int)strlen(new_data_c) + 1, - TNG_MAX_STR_LEN); - if(second_dim_values[k]) - { - free(second_dim_values[k]); - } - second_dim_values[k] = malloc(len); - if(!second_dim_values[k]) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", - len, __FILE__, __LINE__); - return(TNG_CRITICAL); - } - strncpy(second_dim_values[k], - new_data_c, len); - new_data_c += len; - } - } - } - } - else - { - switch(datatype) - { - case TNG_INT_DATA: - size = sizeof(int64_t); - break; - case TNG_FLOAT_DATA: - size = sizeof(float); - break; - case TNG_DOUBLE_DATA: - default: - size = sizeof(double); - } +tng_function_status DECLSPECDLLEXPORT tng_file_headers_read + (const tng_trajectory_t tng_data, + const char hash_mode) +{ + int64_t prev_pos = 0; + tng_gen_block_t block; + + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - memcpy(data->values, new_data, size * n_frames_div * - n_particles * n_values_per_frame); - } + tng_data->n_trajectory_frame_sets = 0; + + if(tng_input_file_init(tng_data) != TNG_SUCCESS) + { + return(TNG_CRITICAL); + } + + fseeko(tng_data->input_file, 0, SEEK_SET); + + tng_block_init(&block); + /* Non trajectory blocks (they come before the trajectory + * blocks in the file) */ + while (prev_pos < tng_data->input_file_len && + tng_block_header_read(tng_data, block) != TNG_CRITICAL && + block->id != -1 && + block->id != TNG_TRAJECTORY_FRAME_SET) + { + tng_block_read_next(tng_data, block, hash_mode); + prev_pos = ftello(tng_data->input_file); + } + + /* Go back if a trajectory block was encountered */ + if(block->id == TNG_TRAJECTORY_FRAME_SET) + { + fseeko(tng_data->input_file, prev_pos, SEEK_SET); } + tng_block_destroy(&block); + return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_data_block_name_get - (tng_trajectory_t tng_data, - int64_t block_id, - char *name, - int max_len) +tng_function_status DECLSPECDLLEXPORT tng_file_headers_write + (const tng_trajectory_t tng_data, + const char hash_mode) { - int64_t i; - tng_trajectory_frame_set_t frame_set; + int i; + int64_t len, orig_len, tot_len = 0, data_start_pos, temp_pos = -1; tng_function_status stat; - tng_particle_data_t p_data; - tng_non_particle_data_t np_data; - int block_type = -1; + tng_gen_block_t block; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); - for(i = 0; i < tng_data->n_particle_data_blocks; i++) + if(tng_output_file_init(tng_data) != TNG_SUCCESS) { - p_data = &tng_data->non_tr_particle_data[i]; - if(p_data->block_id == block_id) - { - strncpy(name, p_data->block_name, max_len); - name[max_len - 1] = '\0'; - return(TNG_SUCCESS); - } + return(TNG_CRITICAL); } - for(i = 0; i < tng_data->n_data_blocks; i++) + + if(tng_data->n_trajectory_frame_sets > 0) { - np_data = &tng_data->non_tr_data[i]; - if(np_data->block_id == block_id) + stat = tng_file_headers_len_get(tng_data, &orig_len); + if(stat != TNG_SUCCESS) { - strncpy(name, np_data->block_name, max_len); - name[max_len - 1] = '\0'; - return(TNG_SUCCESS); + return(stat); } - } - - frame_set = &tng_data->current_trajectory_frame_set; - stat = tng_particle_data_find(tng_data, block_id, &p_data); - if(stat == TNG_SUCCESS) - { - block_type = TNG_PARTICLE_BLOCK_DATA; - } - else - { - stat = tng_data_find(tng_data, block_id, &np_data); - if(stat == TNG_SUCCESS) + tng_block_init(&block); + block->name = malloc(TNG_MAX_STR_LEN); + if(!block->name) { - block_type = TNG_NON_PARTICLE_BLOCK_DATA; + fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", + TNG_MAX_STR_LEN, __FILE__, __LINE__); + tng_block_destroy(&block); + return(TNG_CRITICAL); } - else + strcpy(block->name, "GENERAL INFO"); + tng_block_header_len_calculate(tng_data, block, &len); + tot_len += len; + tng_general_info_block_len_calculate(tng_data, &len); + tot_len += len; + strcpy(block->name, "MOLECULES"); + tng_block_header_len_calculate(tng_data, block, &len); + tot_len += len; + tng_molecules_block_len_calculate(tng_data, &len); + tot_len += len; + + for(i = 0; i < tng_data->n_data_blocks; i++) { - stat = tng_frame_set_read_current_only_data_from_block_id(tng_data, TNG_USE_HASH, block_id); - if(stat != TNG_SUCCESS) - { - return(stat); - } - stat = tng_particle_data_find(tng_data, block_id, &p_data); - if(stat == TNG_SUCCESS) - { - block_type = TNG_PARTICLE_BLOCK_DATA; - } - else - { - stat = tng_data_find(tng_data, block_id, &np_data); - if(stat == TNG_SUCCESS) - { - block_type = TNG_NON_PARTICLE_BLOCK_DATA; - } - } + strcpy(block->name, tng_data->non_tr_data[i].block_name); + tng_block_header_len_calculate(tng_data, block, &len); + tot_len += len; + tng_data_block_len_calculate(tng_data, + (tng_data_t)&tng_data->non_tr_data[i], + TNG_FALSE, 1, 1, 1, 0, 1, + &data_start_pos, + &len); + tot_len += len; } - } - if(block_type == TNG_PARTICLE_BLOCK_DATA) - { - for(i = 0; i < frame_set->n_particle_data_blocks; i++) + for(i = 0; i < tng_data->n_particle_data_blocks; i++) { - p_data = &frame_set->tr_particle_data[i]; - if(p_data->block_id == block_id) - { - strncpy(name, p_data->block_name, max_len); - name[max_len - 1] = '\0'; - return(TNG_SUCCESS); - } + strcpy(block->name, tng_data->non_tr_particle_data[i].block_name); + tng_block_header_len_calculate(tng_data, block, &len); + tot_len += len; + tng_data_block_len_calculate(tng_data, + &tng_data->non_tr_particle_data[i], + TNG_TRUE, 1, 1, 1, 0, + tng_data->n_particles, + &data_start_pos, + &len); + tot_len += len; } - } - else if(block_type == TNG_NON_PARTICLE_BLOCK_DATA) - { - for(i = 0; i < frame_set->n_data_blocks; i++) + tng_block_destroy(&block); + + if(tot_len > orig_len) { - np_data = &frame_set->tr_data[i]; - if(np_data->block_id == block_id) - { - strncpy(name, np_data->block_name, max_len); - name[max_len - 1] = '\0'; - return(TNG_SUCCESS); - } + tng_migrate_data_in_file(tng_data, orig_len+1, tot_len - orig_len, hash_mode); } - } - return(TNG_FAILURE); -} + stat = tng_reread_frame_set_at_file_pos(tng_data, tng_data->last_trajectory_frame_set_input_file_pos); + if(stat == TNG_CRITICAL) + { + fprintf(stderr, "TNG library: Cannot read frame set. %s: %d\n", + __FILE__, __LINE__); + return(TNG_CRITICAL); + } -tng_function_status DECLSPECDLLEXPORT tng_data_block_dependency_get - (const tng_trajectory_t tng_data, - int64_t block_id, - int *block_dependency) -{ - int64_t i; - tng_function_status stat; - tng_particle_data_t p_data; - tng_non_particle_data_t np_data; + /* In order to write non-trajectory data the current_trajectory_frame_set_output_file_pos + * must temporarily be reset */ + temp_pos = tng_data->current_trajectory_frame_set_output_file_pos; + tng_data->current_trajectory_frame_set_output_file_pos = -1; + } - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(block_dependency, "TNG library: block_dependency must not be a NULL pointer."); + if(tng_general_info_block_write(tng_data, hash_mode) + != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Error writing general info block of file %s. %s: %d\n", + tng_data->input_file_path, __FILE__, __LINE__); + return(TNG_CRITICAL); + } - for(i = 0; i < tng_data->n_particle_data_blocks; i++) + if(tng_molecules_block_write(tng_data, hash_mode) + != TNG_SUCCESS) { - p_data = &tng_data->non_tr_particle_data[i]; - if(p_data->block_id == block_id) - { - *block_dependency = TNG_PARTICLE_DEPENDENT; - return(TNG_SUCCESS); - } + fprintf(stderr, "TNG library: Error writing atom names block of file %s. %s: %d\n", + tng_data->input_file_path, __FILE__, __LINE__); + return(TNG_CRITICAL); } + + /* FIXME: Currently writing non-trajectory data blocks here. + * Should perhaps be moved. */ + tng_block_init(&block); for(i = 0; i < tng_data->n_data_blocks; i++) { - np_data = &tng_data->non_tr_data[i]; - if(np_data->block_id == block_id) - { - *block_dependency = 0; - return(TNG_SUCCESS); - } + block->id = tng_data->non_tr_data[i].block_id; + tng_data_block_write(tng_data, block, + i, TNG_FALSE, 0, hash_mode); } - stat = tng_particle_data_find(tng_data, block_id, &p_data); - if(stat == TNG_SUCCESS) + for(i = 0; i < tng_data->n_particle_data_blocks; i++) { - *block_dependency = TNG_PARTICLE_DEPENDENT + TNG_FRAME_DEPENDENT; - return(TNG_SUCCESS); + block->id = tng_data->non_tr_particle_data[i].block_id; + tng_data_block_write(tng_data, block, + i, TNG_TRUE, 0, hash_mode); } - else + + tng_block_destroy(&block); + + /* Continue writing at the end of the file. */ + fseeko(tng_data->output_file, 0, SEEK_END); + if(temp_pos > 0) { - stat = tng_data_find(tng_data, block_id, &np_data); - if(stat == TNG_SUCCESS) - { - *block_dependency = TNG_FRAME_DEPENDENT; - return(TNG_SUCCESS); - } - else - { - stat = tng_frame_set_read_current_only_data_from_block_id(tng_data, TNG_USE_HASH, block_id); - if(stat != TNG_SUCCESS) - { - return(stat); - } - stat = tng_particle_data_find(tng_data, block_id, &p_data); - if(stat == TNG_SUCCESS) - { - *block_dependency = TNG_PARTICLE_DEPENDENT + TNG_FRAME_DEPENDENT; - return(TNG_SUCCESS); - } - else - { - stat = tng_data_find(tng_data, block_id, &np_data); - if(stat == TNG_SUCCESS) - { - *block_dependency = TNG_FRAME_DEPENDENT; - return(TNG_SUCCESS); - } - } - } + tng_data->current_trajectory_frame_set_output_file_pos = temp_pos; } - return(TNG_FAILURE); + return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_data_block_num_values_per_frame_get +tng_function_status DECLSPECDLLEXPORT tng_block_read_next (const tng_trajectory_t tng_data, - int64_t block_id, - int64_t *n_values_per_frame) + const tng_gen_block_t block, + const char hash_mode) { - int64_t i; - tng_function_status stat; - tng_particle_data_t p_data; - tng_non_particle_data_t np_data; - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); - - for(i = 0; i < tng_data->n_particle_data_blocks; i++) - { - p_data = &tng_data->non_tr_particle_data[i]; - if(p_data->block_id == block_id) - { - *n_values_per_frame = p_data->n_values_per_frame; - return(TNG_SUCCESS); - } - } - for(i = 0; i < tng_data->n_data_blocks; i++) - { - np_data = &tng_data->non_tr_data[i]; - if(np_data->block_id == block_id) - { - *n_values_per_frame = np_data->n_values_per_frame; - return(TNG_SUCCESS); - } - } + TNG_ASSERT(block, "TNG library: block must be initialised and must not be a NULL pointer."); - stat = tng_particle_data_find(tng_data, block_id, &p_data); - if(stat == TNG_SUCCESS) - { - *n_values_per_frame = p_data->n_values_per_frame; - return(TNG_SUCCESS); - } - else + switch(block->id) { - stat = tng_data_find(tng_data, block_id, &np_data); - if(stat == TNG_SUCCESS) + case TNG_TRAJECTORY_FRAME_SET: + return(tng_frame_set_block_read(tng_data, block, hash_mode)); + case TNG_PARTICLE_MAPPING: + return(tng_trajectory_mapping_block_read(tng_data, block, hash_mode)); + case TNG_GENERAL_INFO: + return(tng_general_info_block_read(tng_data, block, hash_mode)); + case TNG_MOLECULES: + return(tng_molecules_block_read(tng_data, block, hash_mode)); + default: + if(block->id >= TNG_TRAJ_BOX_SHAPE) { - *n_values_per_frame = np_data->n_values_per_frame; - return(TNG_SUCCESS); + return(tng_data_block_contents_read(tng_data, block, hash_mode)); } else { - stat = tng_frame_set_read_current_only_data_from_block_id(tng_data, TNG_USE_HASH, block_id); - if(stat != TNG_SUCCESS) - { - return(stat); - } - stat = tng_particle_data_find(tng_data, block_id, &p_data); - if(stat == TNG_SUCCESS) - { - *n_values_per_frame = p_data->n_values_per_frame; - return(TNG_SUCCESS); - } - else - { - stat = tng_data_find(tng_data, block_id, &np_data); - if(stat == TNG_SUCCESS) - { - *n_values_per_frame = np_data->n_values_per_frame; - return(TNG_SUCCESS); - } - } + /* Skip to the next block */ + fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR); + return(TNG_FAILURE); } } - - return(TNG_FAILURE); } -tng_function_status DECLSPECDLLEXPORT tng_frame_data_write - (tng_trajectory_t tng_data, - const int64_t frame_nr, - const int64_t block_id, - const void *values, +tng_function_status DECLSPECDLLEXPORT tng_frame_set_read + (const tng_trajectory_t tng_data, const char hash_mode) { - int64_t header_pos, file_pos; - int64_t output_file_len, n_values_per_frame, size, contents_size; - int64_t header_size, temp_first, temp_last; - int64_t i, last_frame, temp_current; + int64_t file_pos; tng_gen_block_t block; - tng_trajectory_frame_set_t frame_set; - FILE *temp = tng_data->input_file; - struct tng_non_particle_data data; tng_function_status stat; - char dependency, sparse_data, datatype; - void *copy; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(frame_nr >= 0, "TNG library: frame_nr must be >= 0."); - TNG_ASSERT(values, "TNG library: values must not be a NULL pointer."); - if(tng_output_file_init(tng_data) != TNG_SUCCESS) + if(tng_input_file_init(tng_data) != TNG_SUCCESS) { - fprintf(stderr, "TNG library: Cannot initialise destination file. %s: %d\n", - __FILE__, __LINE__); return(TNG_CRITICAL); } - temp_first = tng_data->first_trajectory_frame_set_input_file_pos; - temp_last = tng_data->last_trajectory_frame_set_input_file_pos; - temp_current = tng_data->current_trajectory_frame_set_input_file_pos; - tng_data->first_trajectory_frame_set_input_file_pos = - tng_data->first_trajectory_frame_set_output_file_pos; - tng_data->last_trajectory_frame_set_input_file_pos = - tng_data->last_trajectory_frame_set_output_file_pos; - tng_data->current_trajectory_frame_set_input_file_pos = - tng_data->current_trajectory_frame_set_output_file_pos; + file_pos = ftello(tng_data->input_file); - tng_data->input_file = tng_data->output_file; + tng_block_init(&block); - stat = tng_frame_set_of_frame_find(tng_data, frame_nr); + /* Read block headers first to see what block is found. */ + stat = tng_block_header_read(tng_data, block); + if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET || + block->id == -1) + { + fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", + file_pos, __FILE__, __LINE__); + tng_block_destroy(&block); + return(TNG_CRITICAL); + } - frame_set = &tng_data->current_trajectory_frame_set; + tng_data->current_trajectory_frame_set_input_file_pos = file_pos; - if(stat != TNG_SUCCESS) + if(tng_block_read_next(tng_data, block, + hash_mode) == TNG_SUCCESS) { - last_frame = frame_set->first_frame + - frame_set->n_frames - 1; - /* If the wanted frame would be in the frame set after the last - * frame set create a new frame set. */ - if(stat == TNG_FAILURE && - last_frame < frame_nr) -/* (last_frame < frame_nr && - tng_data->current_trajectory_frame_set.first_frame + - tng_data->frame_set_n_frames >= frame_nr))*/ + tng_data->n_trajectory_frame_sets++; + file_pos = ftello(tng_data->input_file); + /* Read all blocks until next frame set block */ + stat = tng_block_header_read(tng_data, block); + while(file_pos < tng_data->input_file_len && + stat != TNG_CRITICAL && + block->id != TNG_TRAJECTORY_FRAME_SET && + block->id != -1) { - if(last_frame + tng_data->frame_set_n_frames < frame_nr) - { - last_frame = frame_nr - 1; - } - tng_frame_set_new(tng_data, - last_frame+1, - tng_data->frame_set_n_frames); - file_pos = ftello(tng_data->output_file); - fseeko(tng_data->output_file, 0, SEEK_END); - output_file_len = ftello(tng_data->output_file); - fseeko(tng_data->output_file, file_pos, SEEK_SET); - - /* Read mapping blocks from the last frame set */ - tng_block_init(&block); - - stat = tng_block_header_read(tng_data, block); - while(file_pos < output_file_len && - stat != TNG_CRITICAL && - block->id != TNG_TRAJECTORY_FRAME_SET && - block->id != -1) + stat = tng_block_read_next(tng_data, block, + hash_mode); + if(stat != TNG_CRITICAL) { - if(block->id == TNG_PARTICLE_MAPPING) - { - tng_trajectory_mapping_block_read(tng_data, block, - hash_mode); - } - else - { - fseeko(tng_data->output_file, block->block_contents_size, - SEEK_CUR); - } - file_pos = ftello(tng_data->output_file); - if(file_pos < output_file_len) + file_pos = ftello(tng_data->input_file); + if(file_pos < tng_data->input_file_len) { stat = tng_block_header_read(tng_data, block); } } - - tng_block_destroy(&block); - /* Write the frame set to disk */ - if(tng_frame_set_write(tng_data, hash_mode) != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Error writing frame set. %s: %d\n", __FILE__, __LINE__); - return(TNG_CRITICAL); - } } - else + if(stat == TNG_CRITICAL) { - tng_data->input_file = temp; - tng_data->first_trajectory_frame_set_input_file_pos = temp_first; - tng_data->last_trajectory_frame_set_input_file_pos = temp_last; - tng_data->current_trajectory_frame_set_input_file_pos = temp_current; + fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", + file_pos, __FILE__, __LINE__); + tng_block_destroy(&block); return(stat); } + + if(block->id == TNG_TRAJECTORY_FRAME_SET) + { + fseeko(tng_data->input_file, file_pos, SEEK_SET); + } } - tng_block_init(&block); + tng_block_destroy(&block); - file_pos = tng_data->current_trajectory_frame_set_output_file_pos; + return(TNG_SUCCESS); +} - fseeko(tng_data->output_file, 0, SEEK_END); - output_file_len = ftello(tng_data->output_file); - fseeko(tng_data->output_file, file_pos, SEEK_SET); - /* Read past the frame set block first */ +tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_current_only_data_from_block_id + (const tng_trajectory_t tng_data, + const char hash_mode, + const int64_t block_id) +{ + int64_t file_pos; + tng_gen_block_t block; + tng_function_status stat; + int found_flag = 1; + + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + + if(tng_input_file_init(tng_data) != TNG_SUCCESS) + { + return(TNG_CRITICAL); + } + + file_pos = tng_data->current_trajectory_frame_set_input_file_pos; + + if(file_pos < 0) + { + /* No current frame set. This means that the first frame set must be + * read */ + found_flag = 0; + file_pos = tng_data->first_trajectory_frame_set_input_file_pos; + } + + if(file_pos > 0) + { + fseeko(tng_data->input_file, + file_pos, + SEEK_SET); + } + else + { + return(TNG_FAILURE); + } + + tng_block_init(&block); + + /* Read block headers first to see what block is found. */ stat = tng_block_header_read(tng_data, block); - if(stat == TNG_CRITICAL) + if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET) { fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", file_pos, __FILE__, __LINE__); tng_block_destroy(&block); - tng_data->input_file = temp; - - tng_data->first_trajectory_frame_set_input_file_pos = temp_first; - tng_data->last_trajectory_frame_set_input_file_pos = temp_last; - tng_data->current_trajectory_frame_set_input_file_pos = temp_current; - return(stat); + return(TNG_CRITICAL); } - fseeko(tng_data->output_file, block->block_contents_size, - SEEK_CUR); + /* If the current frame set had already been read skip its block contents */ + if(found_flag) + { + fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR); + } + /* Otherwise read the frame set block */ + else + { + stat = tng_block_read_next(tng_data, block, + hash_mode); + if(stat != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot read frame set block. %s: %d\n", __FILE__, __LINE__); + tng_block_destroy(&block); + return(stat); + } + } + file_pos = ftello(tng_data->input_file); - /* Read all block headers until next frame set block or - * until the wanted block id is found */ + found_flag = 0; + + /* Read only blocks of the requested ID + * until next frame set block */ stat = tng_block_header_read(tng_data, block); - while(file_pos < output_file_len && - stat != TNG_CRITICAL && - block->id != block_id && - block->id != TNG_TRAJECTORY_FRAME_SET && - block->id != -1) + while(file_pos < tng_data->input_file_len && + stat != TNG_CRITICAL && + block->id != TNG_TRAJECTORY_FRAME_SET && + block->id != -1) { - fseeko(tng_data->output_file, block->block_contents_size, SEEK_CUR); - file_pos = ftello(tng_data->output_file); - if(file_pos < output_file_len) + if(block->id == block_id) { - stat = tng_block_header_read(tng_data, block); + stat = tng_block_read_next(tng_data, block, + hash_mode); + if(stat != TNG_CRITICAL) + { + file_pos = ftello(tng_data->input_file); + found_flag = 1; + if(file_pos < tng_data->input_file_len) + { + stat = tng_block_header_read(tng_data, block); + } + } + } + else + { + file_pos += block->block_contents_size + block->header_contents_size; + fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR); + if(file_pos < tng_data->input_file_len) + { + stat = tng_block_header_read(tng_data, block); + } } } if(stat == TNG_CRITICAL) { fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", - file_pos, __FILE__, __LINE__); + file_pos, __FILE__, __LINE__); tng_block_destroy(&block); - tng_data->input_file = temp; - tng_data->first_trajectory_frame_set_input_file_pos = temp_first; - tng_data->last_trajectory_frame_set_input_file_pos = temp_last; - tng_data->current_trajectory_frame_set_input_file_pos = temp_current; return(stat); } - contents_size = block->block_contents_size; - header_size = block->header_contents_size; + if(block->id == TNG_TRAJECTORY_FRAME_SET) + { + fseeko(tng_data->input_file, file_pos, SEEK_SET); + } - header_pos = ftello(tng_data->output_file) - header_size; - frame_set = &tng_data->current_trajectory_frame_set; + tng_block_destroy(&block); - if(fread(&datatype, sizeof(datatype), 1, tng_data->input_file) == 0) + if(found_flag) { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); + return(TNG_SUCCESS); } - if(fread(&dependency, sizeof(dependency), 1, tng_data->input_file) == 0) + else { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); + return(TNG_FAILURE); } - data.datatype = datatype; +} - if(!(dependency & TNG_FRAME_DEPENDENT) || - (dependency & TNG_PARTICLE_DEPENDENT)) - { - tng_block_destroy(&block); - tng_data->input_file = temp; +tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_next + (const tng_trajectory_t tng_data, + const char hash_mode) +{ + int64_t file_pos; - tng_data->first_trajectory_frame_set_input_file_pos = temp_first; - tng_data->last_trajectory_frame_set_input_file_pos = temp_last; - tng_data->current_trajectory_frame_set_input_file_pos = temp_current; - return(TNG_FAILURE); - } + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - if(fread(&sparse_data, sizeof(sparse_data), 1, tng_data->input_file) == 0) + if(tng_input_file_init(tng_data) != TNG_SUCCESS) { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); return(TNG_CRITICAL); } - if(fread(&data.n_values_per_frame, sizeof(data.n_values_per_frame), 1, - tng_data->input_file) == 0) + file_pos = tng_data->current_trajectory_frame_set.next_frame_set_file_pos; + + if(file_pos < 0 && tng_data->current_trajectory_frame_set_input_file_pos <= 0) { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); + file_pos = tng_data->first_trajectory_frame_set_input_file_pos; } - if(tng_data->output_endianness_swap_func_64) + + if(file_pos > 0) { - if(tng_data->output_endianness_swap_func_64(tng_data, - &data.n_values_per_frame) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + fseeko(tng_data->input_file, + file_pos, + SEEK_SET); + } + else + { + return(TNG_FAILURE); } - if(fread(&data.codec_id, sizeof(data.codec_id), 1, - tng_data->input_file) == 0) + return(tng_frame_set_read(tng_data, hash_mode)); +} + +tng_function_status DECLSPECDLLEXPORT tng_frame_set_read_next_only_data_from_block_id + (const tng_trajectory_t tng_data, + const char hash_mode, + const int64_t block_id) +{ + int64_t file_pos; + tng_gen_block_t block; + tng_function_status stat; + + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + + if(tng_input_file_init(tng_data) != TNG_SUCCESS) { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); return(TNG_CRITICAL); } - if(tng_data->output_endianness_swap_func_64) + + file_pos = tng_data->current_trajectory_frame_set.next_frame_set_file_pos; + + if(file_pos < 0 && tng_data->current_trajectory_frame_set_input_file_pos <= 0) { - if(tng_data->output_endianness_swap_func_64(tng_data, - &data.codec_id) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + file_pos = tng_data->first_trajectory_frame_set_input_file_pos; } - if(data.codec_id != TNG_UNCOMPRESSED) + if(file_pos > 0) { - if(fread(&data.compression_multiplier, - sizeof(data.compression_multiplier), 1, tng_data->input_file) - == 0) - { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); - } - if(tng_data->output_endianness_swap_func_64) - { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)&data.compression_multiplier) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } + fseeko(tng_data->input_file, + file_pos, + SEEK_SET); } else { - data.compression_multiplier = 1; + return(TNG_FAILURE); } - if(sparse_data) - { - if(fread(&data.first_frame_with_data, sizeof(data.first_frame_with_data), - 1, tng_data->input_file) == 0) - { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); - } - if(tng_data->output_endianness_swap_func_64) - { - if(tng_data->output_endianness_swap_func_64(tng_data, - &data.first_frame_with_data) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } + tng_block_init(&block); - if(fread(&data.stride_length, sizeof(data.stride_length), - 1, tng_data->input_file) == 0) - { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); - } - if(tng_data->output_endianness_swap_func_64) - { - if(tng_data->output_endianness_swap_func_64(tng_data, - &data.stride_length) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } + /* Read block headers first to see what block is found. */ + stat = tng_block_header_read(tng_data, block); + if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET) + { + fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", + file_pos, __FILE__, __LINE__); + tng_block_destroy(&block); + return(TNG_CRITICAL); } - else + + tng_data->current_trajectory_frame_set_input_file_pos = file_pos; + + if(tng_block_read_next(tng_data, block, + hash_mode) == TNG_SUCCESS) { - data.first_frame_with_data = 0; - data.stride_length = 1; + stat = tng_frame_set_read_current_only_data_from_block_id(tng_data, hash_mode, block_id); } - data.n_frames = tng_data->current_trajectory_frame_set.n_frames; - tng_data->input_file = temp; + tng_block_destroy(&block); - tng_data->first_trajectory_frame_set_input_file_pos = temp_first; - tng_data->last_trajectory_frame_set_input_file_pos = temp_last; - tng_data->current_trajectory_frame_set_input_file_pos = temp_current; + return(stat); +} - switch(data.datatype) +tng_function_status tng_frame_set_write + (const tng_trajectory_t tng_data, + const char hash_mode) +{ + int i, j; + tng_gen_block_t block; + tng_trajectory_frame_set_t frame_set; + tng_function_status stat; + + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + + frame_set = &tng_data->current_trajectory_frame_set; + + if(frame_set->n_written_frames == frame_set->n_frames) { - case(TNG_INT_DATA): - size = sizeof(int64_t); - break; - case(TNG_FLOAT_DATA): - size = sizeof(float); - break; - case(TNG_DOUBLE_DATA): - size = sizeof(double); - break; - default: - fprintf(stderr, "TNG library: Cannot calculate writing locations. %s: %d.\n", __FILE__, - __LINE__); - tng_block_destroy(&block); - return(TNG_FAILURE); + return(TNG_SUCCESS); } - n_values_per_frame = data.n_values_per_frame; + tng_data->current_trajectory_frame_set_output_file_pos = + ftello(tng_data->output_file); + tng_data->last_trajectory_frame_set_output_file_pos = + tng_data->current_trajectory_frame_set_output_file_pos; - file_pos = (frame_nr - tng_max_i64(frame_set->first_frame, - data.first_frame_with_data)) / - data.stride_length; - file_pos *= size * n_values_per_frame; + if(tng_data->current_trajectory_frame_set_output_file_pos <= 0) + { + return(TNG_FAILURE); + } - if(file_pos > contents_size) + if(tng_data->first_trajectory_frame_set_output_file_pos == -1) + { + tng_data->first_trajectory_frame_set_output_file_pos = + tng_data->current_trajectory_frame_set_output_file_pos; + } + + tng_block_init(&block); + + if(tng_frame_set_block_write(tng_data, block, hash_mode) != TNG_SUCCESS) { - fprintf(stderr, "TNG library: Attempting to write outside the block. %s: %d\n", __FILE__, - __LINE__); tng_block_destroy(&block); return(TNG_FAILURE); } - fseeko(tng_data->output_file, file_pos, SEEK_CUR); - - /* If the endianness is not big endian the data needs to be swapped */ - if((data.datatype == TNG_INT_DATA || - data.datatype == TNG_DOUBLE_DATA) && - tng_data->output_endianness_swap_func_64) + /* Write non-particle data blocks */ + for(i = 0; in_data_blocks; i++) { - copy = malloc(n_values_per_frame * size); - memcpy(copy, values, n_values_per_frame * size); - for(i = 0; i < n_values_per_frame; i++) - { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)copy+i) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } - } - fwrite(copy, n_values_per_frame, size, - tng_data->output_file); - free(copy); + block->id = frame_set->tr_data[i].block_id; + tng_data_block_write(tng_data, block, i, TNG_FALSE, 0, hash_mode); } - else if(data.datatype == TNG_FLOAT_DATA && - tng_data->output_endianness_swap_func_32) + /* Write the mapping blocks and particle data blocks*/ + if(frame_set->n_mapping_blocks) { - copy = malloc(n_values_per_frame * size); - memcpy(copy, values, n_values_per_frame * size); - for(i = 0; i < n_values_per_frame; i++) + for(i = 0; i < frame_set->n_mapping_blocks; i++) { - if(tng_data->output_endianness_swap_func_32(tng_data, - (int32_t *)copy+i) - != TNG_SUCCESS) + block->id = TNG_PARTICLE_MAPPING; + if(frame_set->mappings[i].n_particles > 0) { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); + tng_trajectory_mapping_block_write(tng_data, block, i, hash_mode); + for(j = 0; jn_particle_data_blocks; j++) + { + block->id = frame_set->tr_particle_data[j].block_id; + tng_data_block_write(tng_data, block, + j, TNG_TRUE, &frame_set->mappings[i], + hash_mode); + } } } - fwrite(copy, n_values_per_frame, size, - tng_data->output_file); - free(copy); } - else { - fwrite(values, n_values_per_frame, size, tng_data->output_file); + for(i = 0; in_particle_data_blocks; i++) + { + block->id = frame_set->tr_particle_data[i].block_id; + tng_data_block_write(tng_data, block, + i, TNG_TRUE, 0, hash_mode); + } } - fflush(tng_data->output_file); - /* Update the number of written frames in the frame set. */ - if(frame_nr - frame_set->first_frame + 1 > frame_set->n_written_frames) - { - frame_set->n_written_frames = frame_nr - frame_set->first_frame + 1; - } + /* Update pointers in the general info block */ + stat = tng_header_pointers_update(tng_data, hash_mode); - /* If the last frame has been written update the hash */ - if(hash_mode == TNG_USE_HASH && (frame_nr + data.stride_length - - data.first_frame_with_data) >= - frame_set->n_frames) + if(stat == TNG_SUCCESS) { - tng_md5_hash_update(tng_data, block, header_pos, header_pos + - header_size); + stat = tng_frame_set_pointers_update(tng_data, hash_mode); } tng_block_destroy(&block); - return(TNG_SUCCESS); + frame_set->n_unwritten_frames = 0; + + fflush(tng_data->output_file); + + return(stat); } -tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write - (tng_trajectory_t tng_data, - const int64_t frame_nr, - const int64_t block_id, - const int64_t val_first_particle, - const int64_t val_n_particles, - const void *values, +tng_function_status DECLSPECDLLEXPORT tng_frame_set_premature_write + (const tng_trajectory_t tng_data, const char hash_mode) { - int64_t header_pos, file_pos, tot_n_particles; - int64_t output_file_len, n_values_per_frame, size, contents_size; - int64_t header_size, temp_first, temp_last; - int64_t mapping_block_end_pos, num_first_particle, block_n_particles; - int64_t i, last_frame, temp_current; + 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 + (const tng_trajectory_t tng_data, + const int64_t first_frame, + const int64_t n_frames) +{ tng_gen_block_t block; tng_trajectory_frame_set_t frame_set; FILE *temp = tng_data->input_file; - struct tng_particle_data data; - tng_function_status stat; - tng_particle_mapping_t mapping; - char dependency, sparse_data, datatype; - void *copy; + int64_t curr_file_pos; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(frame_nr >= 0, "TNG library: frame_nr must be >= 0."); - TNG_ASSERT(values, "TNG library: values must not be a NULL pointer."); - TNG_ASSERT(val_first_particle >= 0, "TNG library: val_first_particle must be >= 0."); - TNG_ASSERT(val_n_particles >= 0, "TNG library: val_n_particles must be >= 0."); + TNG_ASSERT(first_frame >= 0, "TNG library: first_frame must be >= 0."); + TNG_ASSERT(n_frames >= 0, "TNG library: n_frames must be >= 0."); - if(tng_output_file_init(tng_data) != TNG_SUCCESS) + frame_set = &tng_data->current_trajectory_frame_set; + + curr_file_pos = ftello(tng_data->output_file); + + if(curr_file_pos <= 10) { - fprintf(stderr, "TNG library: Cannot initialise destination file. %s: %d\n", - __FILE__, __LINE__); - return(TNG_CRITICAL); + tng_file_headers_write(tng_data, TNG_USE_HASH); } - temp_first = tng_data->first_trajectory_frame_set_input_file_pos; - temp_last = tng_data->last_trajectory_frame_set_input_file_pos; - temp_current = tng_data->current_trajectory_frame_set_input_file_pos; - tng_data->first_trajectory_frame_set_input_file_pos = - tng_data->first_trajectory_frame_set_output_file_pos; - tng_data->last_trajectory_frame_set_input_file_pos = - tng_data->last_trajectory_frame_set_output_file_pos; - tng_data->current_trajectory_frame_set_input_file_pos = - tng_data->current_trajectory_frame_set_output_file_pos; + /* Set pointer to previous frame set to the one that was loaded + * before. + * FIXME: This is a bit risky. If they are not added in order + * it will be wrong. */ + if(tng_data->n_trajectory_frame_sets) + { + frame_set->prev_frame_set_file_pos = + tng_data->last_trajectory_frame_set_output_file_pos; + } - tng_data->input_file = tng_data->output_file; + frame_set->next_frame_set_file_pos = -1; - stat = tng_frame_set_of_frame_find(tng_data, frame_nr); + tng_data->current_trajectory_frame_set_output_file_pos = + ftello(tng_data->output_file); - frame_set = &tng_data->current_trajectory_frame_set; + tng_data->n_trajectory_frame_sets++; - if(stat != TNG_SUCCESS) + /* Set the medium range pointers */ + if(tng_data->n_trajectory_frame_sets == tng_data->medium_stride_length + 1) { - last_frame = frame_set->first_frame + - frame_set->n_frames - 1; -/* fprintf(stderr, "TNG library: Frame %"PRId64" not found. Last frame: %"PRId64"\n", frame_nr, - last_frame); */ - /* If the wanted frame would be in the frame set after the last - * frame set create a new frame set. */ - if(stat == TNG_FAILURE && - (last_frame < frame_nr && - last_frame + tng_data->frame_set_n_frames >= frame_nr)) + frame_set->medium_stride_prev_frame_set_file_pos = + tng_data->first_trajectory_frame_set_output_file_pos; + } + else if(tng_data->n_trajectory_frame_sets > tng_data->medium_stride_length + 1) + { + /* FIXME: Currently only working if the previous frame set has its + * medium stride pointer already set. This might need some fixing. */ + if(frame_set->medium_stride_prev_frame_set_file_pos != -1 && + frame_set->medium_stride_prev_frame_set_file_pos != 0) { - if(last_frame + tng_data->frame_set_n_frames < frame_nr) + tng_block_init(&block); + tng_data->input_file = tng_data->output_file; + + curr_file_pos = ftello(tng_data->output_file); + fseeko(tng_data->output_file, + frame_set->medium_stride_prev_frame_set_file_pos, + SEEK_SET); + + if(tng_block_header_read(tng_data, block) != TNG_SUCCESS) { - last_frame = frame_nr - 1; + fprintf(stderr, "TNG library: Cannot read frame set header. %s: %d\n", + __FILE__, __LINE__); + tng_data->input_file = temp; + tng_block_destroy(&block); + return(TNG_CRITICAL); } - tng_frame_set_new(tng_data, - last_frame+1, - tng_data->frame_set_n_frames); - - file_pos = ftello(tng_data->output_file); - fseeko(tng_data->output_file, 0, SEEK_END); - output_file_len = ftello(tng_data->output_file); - fseeko(tng_data->output_file, file_pos, SEEK_SET); - /* Read mapping blocks from the last frame set */ - tng_block_init(&block); + /* Read the next frame set from the previous frame set and one + * medium stride step back */ + fseeko(tng_data->output_file, block->block_contents_size - (6 * + sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR); + if(fread(&frame_set->medium_stride_prev_frame_set_file_pos, + sizeof(frame_set->medium_stride_prev_frame_set_file_pos), + 1, tng_data->output_file) == 0) + { + fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, __LINE__); + tng_data->input_file = temp; + tng_block_destroy(&block); + return(TNG_CRITICAL); + } - stat = tng_block_header_read(tng_data, block); - while(file_pos < output_file_len && - stat != TNG_CRITICAL && - block->id != TNG_TRAJECTORY_FRAME_SET && - block->id != -1) + if(tng_data->input_endianness_swap_func_64) { - if(block->id == TNG_PARTICLE_MAPPING) - { - tng_trajectory_mapping_block_read(tng_data, block, - hash_mode); - } - else - { - fseeko(tng_data->output_file, block->block_contents_size, - SEEK_CUR); - } - file_pos = ftello(tng_data->output_file); - if(file_pos < output_file_len) + if(tng_data->input_endianness_swap_func_64(tng_data, + &frame_set->medium_stride_prev_frame_set_file_pos) + != TNG_SUCCESS) { - stat = tng_block_header_read(tng_data, block); + fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); } } tng_block_destroy(&block); - /* Write the frame set to disk */ - if(tng_frame_set_write(tng_data, hash_mode) != TNG_SUCCESS) + + /* Set the long range pointers */ + if(tng_data->n_trajectory_frame_sets == tng_data->long_stride_length + 1) { - fprintf(stderr, "TNG library: Error writing frame set. %s: %d\n", __FILE__, __LINE__); - exit(1); + frame_set->long_stride_prev_frame_set_file_pos = + tng_data->first_trajectory_frame_set_output_file_pos; } - } - else - { + else if(tng_data->n_trajectory_frame_sets > tng_data->medium_stride_length + 1) + { + /* FIXME: Currently only working if the previous frame set has its + * long stride pointer already set. This might need some fixing. */ + if(frame_set->long_stride_prev_frame_set_file_pos != -1 && + frame_set->long_stride_prev_frame_set_file_pos != 0) + { + tng_block_init(&block); + tng_data->input_file = tng_data->output_file; + + fseeko(tng_data->output_file, + frame_set->long_stride_prev_frame_set_file_pos, + SEEK_SET); + + if(tng_block_header_read(tng_data, block) != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot read frame set header. %s: %d\n", + __FILE__, __LINE__); + tng_data->input_file = temp; + tng_block_destroy(&block); + return(TNG_CRITICAL); + } + + /* Read the next frame set from the previous frame set and one + * long stride step back */ + fseeko(tng_data->output_file, block->block_contents_size - (6 * + sizeof(int64_t) + 2 * sizeof(double)), SEEK_CUR); + + tng_block_destroy(&block); + + if(fread(&frame_set->long_stride_prev_frame_set_file_pos, + sizeof(frame_set->long_stride_prev_frame_set_file_pos), + 1, tng_data->output_file) == 0) + { + fprintf(stderr, "TNG library: Cannot read block. %s: %d\n", __FILE__, __LINE__); + tng_data->input_file = temp; + return(TNG_CRITICAL); + } + + if(tng_data->input_endianness_swap_func_64) + { + if(tng_data->input_endianness_swap_func_64(tng_data, + &frame_set->long_stride_prev_frame_set_file_pos) + != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); + } + } + + } + } + tng_data->input_file = temp; - tng_data->first_trajectory_frame_set_input_file_pos = temp_first; - tng_data->last_trajectory_frame_set_input_file_pos = temp_last; - tng_data->current_trajectory_frame_set_input_file_pos = temp_current; - return(stat); + fseeko(tng_data->output_file, curr_file_pos, SEEK_SET); } } + frame_set->first_frame = first_frame; + frame_set->n_frames = n_frames; + frame_set->n_written_frames = 0; + frame_set->n_unwritten_frames = 0; + frame_set->first_frame_time = -1; + + if(tng_data->first_trajectory_frame_set_output_file_pos == -1 || + tng_data->first_trajectory_frame_set_output_file_pos == 0) + { + tng_data->first_trajectory_frame_set_output_file_pos = + tng_data->current_trajectory_frame_set_output_file_pos; + } + /* FIXME: Should check the frame number instead of the file_pos, + * in case frame sets are not in order */ + if(tng_data->last_trajectory_frame_set_output_file_pos == -1 || + tng_data->last_trajectory_frame_set_output_file_pos == 0 || + tng_data->last_trajectory_frame_set_output_file_pos < + tng_data->current_trajectory_frame_set_output_file_pos) + { + tng_data->last_trajectory_frame_set_output_file_pos = + tng_data->current_trajectory_frame_set_output_file_pos; + } + + return(TNG_SUCCESS); +} - tng_block_init(&block); +tng_function_status DECLSPECDLLEXPORT tng_frame_set_with_time_new + (const tng_trajectory_t tng_data, + const int64_t first_frame, + const int64_t n_frames, + const double first_frame_time) +{ + tng_function_status stat; - file_pos = tng_data->current_trajectory_frame_set_output_file_pos; + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(first_frame >= 0, "TNG library: first_frame must be >= 0."); + TNG_ASSERT(n_frames >= 0, "TNG library: n_frames must be >= 0."); + TNG_ASSERT(first_frame_time >= 0, "TNG library: first_frame_time must be >= 0."); - fseeko(tng_data->output_file, 0, SEEK_END); - output_file_len = ftello(tng_data->output_file); - fseeko(tng_data->output_file, file_pos, SEEK_SET); - /* Read past the frame set block first */ - stat = tng_block_header_read(tng_data, block); - if(stat == TNG_CRITICAL) + stat = tng_frame_set_new(tng_data, first_frame, n_frames); + if(stat != TNG_SUCCESS) { - fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", - file_pos, __FILE__, __LINE__); - tng_block_destroy(&block); - tng_data->input_file = temp; - - tng_data->first_trajectory_frame_set_input_file_pos = temp_first; - tng_data->last_trajectory_frame_set_input_file_pos = temp_last; - tng_data->current_trajectory_frame_set_input_file_pos = temp_current; return(stat); } - fseeko(tng_data->output_file, block->block_contents_size, - SEEK_CUR); + stat = tng_frame_set_first_frame_time_set(tng_data, first_frame_time); - if(tng_data->var_num_atoms_flag) + return(stat); +} + +tng_function_status DECLSPECDLLEXPORT tng_frame_set_first_frame_time_set + (const tng_trajectory_t tng_data, + const double first_frame_time) +{ + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(first_frame_time >= 0, "TNG library: first_frame_time must be >= 0."); + + tng_data->current_trajectory_frame_set.first_frame_time = first_frame_time; + + return(TNG_SUCCESS); +} + +tng_function_status DECLSPECDLLEXPORT tng_first_frame_nr_of_next_frame_set_get + (const tng_trajectory_t tng_data, + int64_t *frame) +{ + int64_t file_pos, next_frame_set_file_pos; + tng_gen_block_t block; + tng_function_status stat; + + tng_trajectory_frame_set_t frame_set; + + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(tng_data->input_file, "TNG library: An input file must be open to find the next frame set"); + TNG_ASSERT(frame, "TNG library: frame must not be a NULL pointer"); + + file_pos = ftello(tng_data->input_file); + + if(tng_data->current_trajectory_frame_set_input_file_pos <= 0) { - tot_n_particles = frame_set->n_particles; + next_frame_set_file_pos = tng_data->first_trajectory_frame_set_input_file_pos; } else { - tot_n_particles = tng_data->n_particles; + frame_set = &tng_data->current_trajectory_frame_set; + next_frame_set_file_pos = frame_set->next_frame_set_file_pos; } - if(val_n_particles < tot_n_particles) + if(next_frame_set_file_pos <= 0) { - mapping_block_end_pos = -1; - /* Read all mapping blocks to find the right place to put the data */ - stat = tng_block_header_read(tng_data, block); - while(file_pos < output_file_len && - stat != TNG_CRITICAL && - block->id != TNG_TRAJECTORY_FRAME_SET && - block->id != -1) - { - if(block->id == TNG_PARTICLE_MAPPING) - { - tng_trajectory_mapping_block_read(tng_data, block, hash_mode); - } - else - { - fseeko(tng_data->output_file, block->block_contents_size, - SEEK_CUR); - } - file_pos = ftello(tng_data->output_file); - if(block->id == TNG_PARTICLE_MAPPING) - { - mapping = &frame_set->mappings[frame_set->n_mapping_blocks - 1]; - if(val_first_particle >= mapping->num_first_particle && - val_first_particle < mapping->num_first_particle + - mapping->n_particles && - val_first_particle + val_n_particles <= - mapping->num_first_particle + mapping->n_particles) - { - mapping_block_end_pos = file_pos; - } - } - if(file_pos < output_file_len) - { - stat = tng_block_header_read(tng_data, block); - } - } - if(stat == TNG_CRITICAL) - { - fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", - file_pos, __FILE__, __LINE__); - tng_block_destroy(&block); - tng_data->input_file = temp; - - tng_data->first_trajectory_frame_set_input_file_pos = temp_first; - tng_data->last_trajectory_frame_set_input_file_pos = temp_last; - tng_data->current_trajectory_frame_set_input_file_pos = temp_current; - return(stat); - } - if(mapping_block_end_pos < 0) - { - tng_block_destroy(&block); - tng_data->input_file = temp; - - tng_data->first_trajectory_frame_set_input_file_pos = temp_first; - tng_data->last_trajectory_frame_set_input_file_pos = temp_last; - tng_data->current_trajectory_frame_set_input_file_pos = temp_current; - return(TNG_FAILURE); - } - fseeko(tng_data->output_file, mapping_block_end_pos, SEEK_SET); + return(TNG_FAILURE); } - /* Read all block headers until next frame set block or - * until the wanted block id is found */ + fseeko(tng_data->input_file, next_frame_set_file_pos, SEEK_SET); + /* Read block headers first to see that a frame set block is found. */ + tng_block_init(&block); stat = tng_block_header_read(tng_data, block); - while(file_pos < output_file_len && - stat != TNG_CRITICAL && - block->id != block_id && - block->id != TNG_PARTICLE_MAPPING && - block->id != TNG_TRAJECTORY_FRAME_SET && - block->id != -1) - { - fseeko(tng_data->output_file, block->block_contents_size, SEEK_CUR); - file_pos = ftello(tng_data->output_file); - if(file_pos < output_file_len) - { - stat = tng_block_header_read(tng_data, block); - } - } - if(stat == TNG_CRITICAL) + if(stat == TNG_CRITICAL || block->id != TNG_TRAJECTORY_FRAME_SET) { fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", - file_pos, __FILE__, __LINE__); - tng_block_destroy(&block); - tng_data->input_file = temp; - - tng_data->first_trajectory_frame_set_input_file_pos = temp_first; - tng_data->last_trajectory_frame_set_input_file_pos = temp_last; - tng_data->current_trajectory_frame_set_input_file_pos = temp_current; - return(stat); + file_pos, __FILE__, __LINE__); + return(TNG_CRITICAL); } +/* if(tng_data->current_trajectory_frame_set_input_file_pos <= 0) + { + tng_block_read_next(tng_data, block, TNG_USE_HASH); + }*/ + tng_block_destroy(&block); - contents_size = block->block_contents_size; - header_size = block->header_contents_size; - - header_pos = ftello(tng_data->output_file) - header_size; - frame_set = &tng_data->current_trajectory_frame_set; - - if(fread(&datatype, sizeof(datatype), 1, tng_data->input_file) == 0) + if(fread(frame, sizeof(int64_t), 1, tng_data->input_file) == 0) { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); + fprintf(stderr, "TNG library: Cannot read first frame of next frame set. %s: %d\n", + __FILE__, __LINE__); return(TNG_CRITICAL); } + fseeko(tng_data->input_file, file_pos, SEEK_SET); - data.datatype = datatype; + return(TNG_SUCCESS); +} - if(fread(&dependency, sizeof(dependency), 1, tng_data->input_file) == 0) - { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); - } +static tng_function_status tng_gen_data_block_add + (const tng_trajectory_t tng_data, + const int64_t id, + const tng_bool is_particle_data, + const char *block_name, + const char datatype, + const char block_type_flag, + int64_t n_frames, + const int64_t n_values_per_frame, + int64_t stride_length, + const int64_t num_first_particle, + const int64_t n_particles, + const int64_t codec_id, + void *new_data) +{ + int i, size, len; + int64_t j, k; + int64_t tot_n_particles, n_frames_div; + char ***first_dim_values, **second_dim_values; + tng_trajectory_frame_set_t frame_set; + tng_data_t data; + char *new_data_c=new_data; + tng_function_status stat; - if(!(dependency & TNG_FRAME_DEPENDENT) || - !(dependency & TNG_PARTICLE_DEPENDENT)) - { - tng_block_destroy(&block); - tng_data->input_file = temp; + frame_set = &tng_data->current_trajectory_frame_set; - tng_data->first_trajectory_frame_set_input_file_pos = temp_first; - tng_data->last_trajectory_frame_set_input_file_pos = temp_last; - tng_data->current_trajectory_frame_set_input_file_pos = temp_current; - return(TNG_FAILURE); + if(stride_length <= 0) + { + stride_length = 1; } - if(fread(&sparse_data, sizeof(sparse_data), 1, tng_data->input_file) == 0) + if(is_particle_data) { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); + stat = tng_particle_data_find(tng_data, id, &data); } - - if(fread(&data.n_values_per_frame, sizeof(data.n_values_per_frame), 1, - tng_data->input_file) == 0) + else { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); + stat = tng_data_find(tng_data, id, &data); } - if(tng_data->output_endianness_swap_func_64) + /* If the block does not exist, create it */ + if(stat != TNG_SUCCESS) { - if(tng_data->output_endianness_swap_func_64(tng_data, - &data.n_values_per_frame) - != TNG_SUCCESS) + if(is_particle_data) + { + stat = tng_particle_data_block_create(tng_data, block_type_flag); + } + else + { + stat = tng_data_block_create(tng_data, block_type_flag); + } + + if(stat != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot create particle data block. %s: %d\n", + __FILE__, __LINE__); + return(TNG_CRITICAL); + } + if(is_particle_data) + { + if(block_type_flag == TNG_TRAJECTORY_BLOCK) + { + data = &frame_set->tr_particle_data[frame_set-> + n_particle_data_blocks - 1]; + } + else + { + data = &tng_data->non_tr_particle_data[tng_data-> + n_particle_data_blocks - 1]; + } + } + else + { + if(block_type_flag == TNG_TRAJECTORY_BLOCK) + { + data = &frame_set->tr_data[frame_set->n_data_blocks - 1]; + } + else + { + data = &tng_data->non_tr_data[tng_data->n_data_blocks - 1]; + } + } + data->block_id = id; + + data->block_name = malloc(strlen(block_name) + 1); + if(!data->block_name) { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); + fprintf(stderr, "TNG library: Cannot allocate memory (%ud bytes). %s: %d\n", + (unsigned int)strlen(block_name)+1, __FILE__, __LINE__); + return(TNG_CRITICAL); } + strncpy(data->block_name, block_name, strlen(block_name) + 1); + + data->values = 0; + /* FIXME: Memory leak from strings. */ + data->strings = 0; + data->last_retrieved_frame = -1; } - if(fread(&data.codec_id, sizeof(data.codec_id), 1, - tng_data->input_file) == 0) + data->datatype = datatype; + data->stride_length = tng_max_i64(stride_length, 1); + data->n_values_per_frame = n_values_per_frame; + data->n_frames = n_frames; + if(is_particle_data) { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); + data->dependency = TNG_PARTICLE_DEPENDENT; } - if(tng_data->output_endianness_swap_func_64) + else { - if(tng_data->output_endianness_swap_func_64(tng_data, - &data.codec_id) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + data->dependency = 0; + } + if(block_type_flag == TNG_TRAJECTORY_BLOCK && + (n_frames > 1 || + frame_set->n_frames == n_frames || + stride_length > 1)) + { + data->dependency += TNG_FRAME_DEPENDENT; } + data->codec_id = codec_id; + data->compression_multiplier = 1.0; + /* FIXME: This can cause problems. */ + data->first_frame_with_data = frame_set->first_frame; - if(data.codec_id != TNG_UNCOMPRESSED) + if(is_particle_data) { - if(fread(&data.compression_multiplier, - sizeof(data.compression_multiplier), 1, tng_data->input_file) - == 0) + if(block_type_flag == TNG_TRAJECTORY_BLOCK && tng_data->var_num_atoms_flag) { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); + tot_n_particles = frame_set->n_particles; } - - if(tng_data->output_endianness_swap_func_64) + else { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *)&data.compression_multiplier) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + tot_n_particles = tng_data->n_particles; } } + /* This is just to keep the compiler happy - avoid it considering tot_n_particles + * uninitialized. */ else { - data.compression_multiplier = 1; + tot_n_particles = 0; } - if(sparse_data) + /* If data values are supplied add that data to the data block. */ + if(new_data_c) { - if(fread(&data.first_frame_with_data, - sizeof(data.first_frame_with_data), - 1, tng_data->input_file) == 0) + /* Allocate memory */ + if(is_particle_data) { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); + stat = tng_allocate_particle_data_mem(tng_data, data, n_frames, + stride_length, tot_n_particles, + n_values_per_frame); } - if(tng_data->output_endianness_swap_func_64) + else { - if(tng_data->output_endianness_swap_func_64(tng_data, - &data.first_frame_with_data) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + stat = tng_allocate_data_mem(tng_data, data, n_frames, stride_length, + n_values_per_frame); } - - if(fread(&data.stride_length, sizeof(data.stride_length), - 1, tng_data->input_file) == 0) + if(stat != TNG_SUCCESS) { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); + fprintf(stderr, "TNG library: Cannot allocate particle data memory. %s: %d\n", + __FILE__, __LINE__); return(TNG_CRITICAL); } - if(tng_data->output_endianness_swap_func_64) + + if(n_frames > frame_set->n_unwritten_frames) { - if(tng_data->output_endianness_swap_func_64(tng_data, - &data.stride_length) - != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); - } + frame_set->n_unwritten_frames = n_frames; } - } - else - { - data.first_frame_with_data = 0; - data.stride_length = 1; - } - data.n_frames = tng_data->current_trajectory_frame_set.n_frames; - if(fread(&num_first_particle, sizeof(num_first_particle), 1, - tng_data->input_file) == 0) - { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); - } - if(tng_data->output_endianness_swap_func_64) - { - if(tng_data->output_endianness_swap_func_64(tng_data, - &num_first_particle) - != TNG_SUCCESS) + n_frames_div = (n_frames % stride_length) ? + n_frames / stride_length + 1: + n_frames / stride_length; + + if(datatype == TNG_CHAR_DATA) { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); + if(is_particle_data) + { + for(i = 0; i < n_frames_div; i++) + { + first_dim_values = data->strings[i]; + for(j = num_first_particle; j < num_first_particle + n_particles; + j++) + { + second_dim_values = first_dim_values[j]; + for(k = 0; k < n_values_per_frame; k++) + { + len = tng_min_size(strlen(new_data_c) + 1, + TNG_MAX_STR_LEN); + if(second_dim_values[k]) + { + free(second_dim_values[k]); + } + second_dim_values[k] = malloc(len); + if(!second_dim_values[k]) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", + len, __FILE__, __LINE__); + return(TNG_CRITICAL); + } + strncpy(second_dim_values[k], + new_data_c, len); + new_data_c += len; + } + } + } + } + else + { + for(i = 0; i < n_frames_div; i++) + { + second_dim_values = data->strings[0][i]; + for(j = 0; j < n_values_per_frame; j++) + { + len = tng_min_size(strlen(new_data_c) + 1, + TNG_MAX_STR_LEN); + if(second_dim_values[j]) + { + free(second_dim_values[j]); + } + second_dim_values[j] = malloc(len); + if(!second_dim_values[j]) + { + fprintf(stderr, "TNG library: Cannot allocate memory (%d bytes). %s: %d\n", + len, __FILE__, __LINE__); + return(TNG_CRITICAL); + } + strncpy(second_dim_values[j], + new_data_c, len); + new_data_c += len; + } + } + } } - } - - if(fread(&block_n_particles, sizeof(block_n_particles), 1, - tng_data->input_file) == 0) - { - fprintf(stderr, "TNG library: Error reading file. %s: %d\n", __FILE__, __LINE__); - tng_block_destroy(&block); - return(TNG_CRITICAL); - } - if(tng_data->output_endianness_swap_func_64) - { - if(tng_data->output_endianness_swap_func_64(tng_data, - &block_n_particles) - != TNG_SUCCESS) + else { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); + switch(datatype) + { + case TNG_INT_DATA: + size = sizeof(int64_t); + break; + case TNG_FLOAT_DATA: + size = sizeof(float); + break; + case TNG_DOUBLE_DATA: + default: + size = sizeof(double); + } + + if(is_particle_data) + { + memcpy(data->values, new_data, size * n_frames_div * + n_particles * n_values_per_frame); + } + else + { + memcpy(data->values, new_data, size * n_frames_div * + n_values_per_frame); + } } } + return(TNG_SUCCESS); +} - tng_data->input_file = temp; +tng_function_status DECLSPECDLLEXPORT tng_data_block_add + (const tng_trajectory_t tng_data, + const int64_t id, + const char *block_name, + const char datatype, + const char block_type_flag, + int64_t n_frames, + const int64_t n_values_per_frame, + int64_t stride_length, + const int64_t codec_id, + void *new_data) +{ + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(block_name, "TNG library: block_name must not be a NULL pointer."); + TNG_ASSERT(n_values_per_frame > 0, "TNG library: n_values_per_frame must be a positive integer."); - tng_data->first_trajectory_frame_set_input_file_pos = temp_first; - tng_data->last_trajectory_frame_set_input_file_pos = temp_last; - tng_data->current_trajectory_frame_set_input_file_pos = temp_current; + return(tng_gen_data_block_add(tng_data, id, TNG_FALSE, block_name, datatype, + block_type_flag, n_frames, n_values_per_frame, + stride_length, 0, 0, codec_id, new_data)); +} + +tng_function_status DECLSPECDLLEXPORT tng_particle_data_block_add + (const tng_trajectory_t tng_data, + const int64_t id, + const char *block_name, + const char datatype, + const char block_type_flag, + int64_t n_frames, + const int64_t n_values_per_frame, + int64_t stride_length, + const int64_t num_first_particle, + const int64_t n_particles, + const int64_t codec_id, + void *new_data) +{ + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(block_name, "TNG library: block_name mustnot be a NULL pointer."); + TNG_ASSERT(n_values_per_frame > 0, "TNG library: n_values_per_frame must be a positive integer."); + TNG_ASSERT(num_first_particle >= 0, "TNG library: num_first_particle must be >= 0."); + TNG_ASSERT(n_particles >= 0, "TNG library: n_particles must be >= 0."); + return(tng_gen_data_block_add(tng_data, id, TNG_TRUE, block_name, datatype, + block_type_flag, n_frames, n_values_per_frame, + stride_length, num_first_particle, n_particles, + codec_id, new_data)); +} - switch(data.datatype) +tng_function_status DECLSPECDLLEXPORT tng_data_block_name_get + (const tng_trajectory_t tng_data, + const int64_t block_id, + char *name, + const int max_len) +{ + int64_t i; + tng_trajectory_frame_set_t frame_set; + tng_function_status stat; + tng_data_t data; + int block_type = -1; + + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(name, "TNG library: name must not be a NULL pointer."); + + for(i = 0; i < tng_data->n_particle_data_blocks; i++) { - case(TNG_INT_DATA): - size = sizeof(int64_t); - break; - case(TNG_FLOAT_DATA): - size = sizeof(float); - break; - case(TNG_DOUBLE_DATA): - size = sizeof(double); - break; - default: - fprintf(stderr, "TNG library: Cannot calculate writing locations. %s: %d.\n", __FILE__, - __LINE__); - tng_block_destroy(&block); - return(TNG_FAILURE); + data = &tng_data->non_tr_particle_data[i]; + if(data->block_id == block_id) + { + strncpy(name, data->block_name, max_len); + name[max_len - 1] = '\0'; + return(TNG_SUCCESS); + } + } + for(i = 0; i < tng_data->n_data_blocks; i++) + { + data = &tng_data->non_tr_data[i]; + if(data->block_id == block_id) + { + strncpy(name, data->block_name, max_len); + name[max_len - 1] = '\0'; + return(TNG_SUCCESS); + } } - n_values_per_frame = data.n_values_per_frame; - - file_pos = (frame_nr - tng_max_i64(frame_set->first_frame, - data.first_frame_with_data)) / - data.stride_length; - file_pos *= block_n_particles * size * n_values_per_frame; + frame_set = &tng_data->current_trajectory_frame_set; - if(file_pos > contents_size) + stat = tng_particle_data_find(tng_data, block_id, &data); + if(stat == TNG_SUCCESS) { - fprintf(stderr, "TNG library: Attempting to write outside the block. %s: %d\n", __FILE__, - __LINE__); - tng_block_destroy(&block); - return(TNG_FAILURE); + block_type = TNG_PARTICLE_BLOCK_DATA; } - - fseeko(tng_data->output_file, file_pos, SEEK_CUR); - - /* If the endianness is not big endian the data needs to be swapped */ - if((data.datatype == TNG_INT_DATA || - data.datatype == TNG_DOUBLE_DATA) && - tng_data->output_endianness_swap_func_64) + else { - copy = malloc(val_n_particles * n_values_per_frame * size); - memcpy(copy, values, val_n_particles * n_values_per_frame * size); - for(i = 0; i < val_n_particles * n_values_per_frame; i++) + stat = tng_data_find(tng_data, block_id, &data); + if(stat == TNG_SUCCESS) { - if(tng_data->output_endianness_swap_func_64(tng_data, - (int64_t *) copy+i) - != TNG_SUCCESS) + block_type = TNG_NON_PARTICLE_BLOCK_DATA; + } + else + { + stat = tng_frame_set_read_current_only_data_from_block_id(tng_data, TNG_USE_HASH, block_id); + if(stat != TNG_SUCCESS) { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); + return(stat); + } + stat = tng_particle_data_find(tng_data, block_id, &data); + if(stat == TNG_SUCCESS) + { + block_type = TNG_PARTICLE_BLOCK_DATA; + } + else + { + stat = tng_data_find(tng_data, block_id, &data); + if(stat == TNG_SUCCESS) + { + block_type = TNG_NON_PARTICLE_BLOCK_DATA; + } } } - fwrite(copy, val_n_particles * n_values_per_frame, size, - tng_data->output_file); - free(copy); } - else if(data.datatype == TNG_FLOAT_DATA && - tng_data->output_endianness_swap_func_32) + if(block_type == TNG_PARTICLE_BLOCK_DATA) { - copy = malloc(val_n_particles * n_values_per_frame * size); - memcpy(copy, values, val_n_particles * n_values_per_frame * size); - for(i = 0; i < val_n_particles * n_values_per_frame; i++) + for(i = 0; i < frame_set->n_particle_data_blocks; i++) { - if(tng_data->output_endianness_swap_func_32(tng_data, - (int32_t *) copy+i) - != TNG_SUCCESS) + data = &frame_set->tr_particle_data[i]; + if(data->block_id == block_id) { - fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", - __FILE__, __LINE__); + strncpy(name, data->block_name, max_len); + name[max_len - 1] = '\0'; + return(TNG_SUCCESS); } } - fwrite(copy, val_n_particles * n_values_per_frame, size, - tng_data->output_file); - free(copy); - } - - else - { - fwrite(values, val_n_particles * n_values_per_frame, size, - tng_data->output_file); - } - fflush(tng_data->output_file); - - /* Update the number of written frames in the frame set. */ - if(frame_nr - frame_set->first_frame + 1 > frame_set->n_written_frames) - { - frame_set->n_written_frames = frame_nr - frame_set->first_frame + 1; } - - /* If the last frame has been written update the hash */ - if(hash_mode == TNG_USE_HASH && (frame_nr + data.stride_length - - data.first_frame_with_data) >= - frame_set->n_frames) + else if(block_type == TNG_NON_PARTICLE_BLOCK_DATA) { - tng_md5_hash_update(tng_data, block, header_pos, header_pos + - header_size); + for(i = 0; i < frame_set->n_data_blocks; i++) + { + data = &frame_set->tr_data[i]; + if(data->block_id == block_id) + { + strncpy(name, data->block_name, max_len); + name[max_len - 1] = '\0'; + return(TNG_SUCCESS); + } + } } - tng_block_destroy(&block); - return(TNG_SUCCESS); + return(TNG_FAILURE); } -static tng_function_status tng_data_values_alloc +tng_function_status DECLSPECDLLEXPORT tng_data_block_dependency_get (const tng_trajectory_t tng_data, - union data_values ***values, - const int64_t n_frames, - const int64_t n_values_per_frame, - const char type) + const int64_t block_id, + int *block_dependency) { int64_t i; tng_function_status stat; + tng_data_t data; - if(n_frames <= 0 || n_values_per_frame <= 0) - { - return(TNG_FAILURE); - } + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(block_dependency, "TNG library: block_dependency must not be a NULL pointer."); - if(*values) + for(i = 0; i < tng_data->n_particle_data_blocks; i++) { - stat = tng_data_values_free(tng_data, *values, n_frames, - n_values_per_frame, - type); - if(stat != TNG_SUCCESS) + data = &tng_data->non_tr_particle_data[i]; + if(data->block_id == block_id) { - fprintf(stderr, "TNG library: Cannot free particle data values. %s: %d\n", - __FILE__, __LINE__); - return(stat); + *block_dependency = TNG_PARTICLE_DEPENDENT; + return(TNG_SUCCESS); } } - *values = malloc(sizeof(union data_values *) * n_frames); - if(!*values) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(union data_values **) * n_frames, - __FILE__, __LINE__); - return(TNG_CRITICAL); - - } - - for(i = 0; i < n_frames; i++) + for(i = 0; i < tng_data->n_data_blocks; i++) { - (*values)[i] = malloc(sizeof(union data_values) * - n_values_per_frame); - if(!(*values)[i]) + data = &tng_data->non_tr_data[i]; + if(data->block_id == block_id) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(union data_values) * n_values_per_frame, - __FILE__, __LINE__); - free(values); - values = 0; - return(TNG_CRITICAL); + *block_dependency = 0; + return(TNG_SUCCESS); } } - return(TNG_SUCCESS); -} - -/* FIXME: This needs ***values */ -tng_function_status DECLSPECDLLEXPORT tng_data_values_free - (const tng_trajectory_t tng_data, - union data_values **values, - const int64_t n_frames, - const int64_t n_values_per_frame, - const char type) -{ - int64_t i, j; - (void)tng_data; - if(values) + stat = tng_particle_data_find(tng_data, block_id, &data); + if(stat == TNG_SUCCESS) { - for(i = 0; i < n_frames; i++) + *block_dependency = TNG_PARTICLE_DEPENDENT + TNG_FRAME_DEPENDENT; + return(TNG_SUCCESS); + } + else + { + stat = tng_data_find(tng_data, block_id, &data); + if(stat == TNG_SUCCESS) { - if(values[i]) + *block_dependency = TNG_FRAME_DEPENDENT; + return(TNG_SUCCESS); + } + else + { + stat = tng_frame_set_read_current_only_data_from_block_id(tng_data, TNG_USE_HASH, block_id); + if(stat != TNG_SUCCESS) { - if(type == TNG_CHAR_DATA) + return(stat); + } + stat = tng_particle_data_find(tng_data, block_id, &data); + if(stat == TNG_SUCCESS) + { + *block_dependency = TNG_PARTICLE_DEPENDENT + TNG_FRAME_DEPENDENT; + return(TNG_SUCCESS); + } + else + { + stat = tng_data_find(tng_data, block_id, &data); + if(stat == TNG_SUCCESS) { - for(j = 0; j < n_values_per_frame; j++) - { - if(values[i][j].c) - { - free(values[i][j].c); - values[i][j].c = 0; - } - } + *block_dependency = TNG_FRAME_DEPENDENT; + return(TNG_SUCCESS); } - free(values[i]); - values[i] = 0; } } - free(values); - values = 0; } - return(TNG_SUCCESS); + return(TNG_FAILURE); } -static tng_function_status tng_particle_data_values_alloc +tng_function_status DECLSPECDLLEXPORT tng_data_block_num_values_per_frame_get (const tng_trajectory_t tng_data, - union data_values ****values, - const int64_t n_frames, - const int64_t n_particles, - const int64_t n_values_per_frame, - const char type) + const int64_t block_id, + int64_t *n_values_per_frame) { - int64_t i, j; + int64_t i; tng_function_status stat; + tng_data_t data; - if(n_particles == 0 || n_values_per_frame == 0) - { - return(TNG_FAILURE); - } + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); - if(*values) + for(i = 0; i < tng_data->n_particle_data_blocks; i++) { - stat = tng_particle_data_values_free(tng_data, *values, n_frames, - n_particles, n_values_per_frame, - type); - if(stat != TNG_SUCCESS) + data = &tng_data->non_tr_particle_data[i]; + if(data->block_id == block_id) { - fprintf(stderr, "TNG library: Cannot free particle data values. %s: %d\n", - __FILE__, __LINE__); - return(stat); + *n_values_per_frame = data->n_values_per_frame; + return(TNG_SUCCESS); } } - *values = malloc(sizeof(union data_values **) * n_frames); - if(!*values) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(union data_values **) * n_frames, - __FILE__, __LINE__); - return(TNG_CRITICAL); - - } - - for(i = 0; i < n_frames; i++) - { - (*values)[i] = malloc(sizeof(union data_values *) * - n_particles); - if(!(*values)[i]) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(union data_values *) * n_particles, - __FILE__, __LINE__); - free(*values); - *values = 0; - return(TNG_CRITICAL); - } - for(j = 0; j < n_particles; j++) - { - (*values)[i][j] = malloc(sizeof(union data_values) * - n_values_per_frame); - if(!(*values)[i][j]) - { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", - sizeof(union data_values *) * n_particles, - __FILE__, __LINE__); - tng_particle_data_values_free(tng_data, *values, n_frames, - n_particles, n_values_per_frame, - type); - *values = 0; - return(TNG_CRITICAL); - } + for(i = 0; i < tng_data->n_data_blocks; i++) + { + data = &tng_data->non_tr_data[i]; + if(data->block_id == block_id) + { + *n_values_per_frame = data->n_values_per_frame; + return(TNG_SUCCESS); } } - return(TNG_SUCCESS); -} - -/* FIXME: This needs ****values */ -tng_function_status DECLSPECDLLEXPORT tng_particle_data_values_free - (const tng_trajectory_t tng_data, - union data_values ***values, - const int64_t n_frames, - const int64_t n_particles, - const int64_t n_values_per_frame, - const char type) -{ - int64_t i, j, k; - (void)tng_data; - if(values) + stat = tng_particle_data_find(tng_data, block_id, &data); + if(stat == TNG_SUCCESS) { - for(i = 0; i < n_frames; i++) + *n_values_per_frame = data->n_values_per_frame; + return(TNG_SUCCESS); + } + else + { + stat = tng_data_find(tng_data, block_id, &data); + if(stat == TNG_SUCCESS) { - if(values[i]) + *n_values_per_frame = data->n_values_per_frame; + return(TNG_SUCCESS); + } + else + { + stat = tng_frame_set_read_current_only_data_from_block_id(tng_data, TNG_USE_HASH, block_id); + if(stat != TNG_SUCCESS) { - for(j = 0; j < n_particles; j++) + return(stat); + } + stat = tng_particle_data_find(tng_data, block_id, &data); + if(stat == TNG_SUCCESS) + { + *n_values_per_frame = data->n_values_per_frame; + return(TNG_SUCCESS); + } + else + { + stat = tng_data_find(tng_data, block_id, &data); + if(stat == TNG_SUCCESS) { - if(type == TNG_CHAR_DATA) - { - for(k = 0; k < n_values_per_frame; k++) - { - if(values[i][j][k].c) - { - free(values[i][j][k].c); - values[i][j][k].c = 0; - } - } - } - free(values[i][j]); - values[i][j] = 0; + *n_values_per_frame = data->n_values_per_frame; + return(TNG_SUCCESS); } - free(values[i]); - values[i] = 0; } } - free(values); - values = 0; } - return(TNG_SUCCESS); + return(TNG_FAILURE); } - -tng_function_status DECLSPECDLLEXPORT tng_data_get - (tng_trajectory_t tng_data, +tng_function_status DECLSPECDLLEXPORT tng_frame_set_n_frames_of_data_block_get + (const tng_trajectory_t tng_data, const int64_t block_id, - union data_values ***values, - int64_t *n_frames, - int64_t *n_values_per_frame, - char *type) + int64_t *n_frames) { - int64_t i, j, file_pos, block_index; - int size; - size_t len; - tng_non_particle_data_t data; - tng_trajectory_frame_set_t frame_set; tng_gen_block_t block; tng_function_status stat; + char datatype, dependency, sparse_data; + int64_t n_values, codec_id, first_frame_with_data, stride_length, curr_n_frames; + int64_t num_first_particle, block_n_particles; + double multiplier; + md5_state_t md5_state; + int found = TNG_FALSE; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(n_frames, "TNG library: n_frames must not be a NULL pointer."); - TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); - TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); - - frame_set = &tng_data->current_trajectory_frame_set; - block_index = -1; - data = 0; + tng_block_init(&block); - if(tng_data_find(tng_data, block_id, &data) != TNG_SUCCESS) + stat = tng_block_header_read(tng_data, block); + /* If the block header could not be read the reading position might not have been + * at the start of a block. Try again from the file position of the current frame + * set. */ + if(stat != TNG_SUCCESS) { - tng_block_init(&block); - file_pos = ftello(tng_data->input_file); - /* Read all blocks until next frame set block */ + fseeko(tng_data->input_file, tng_data->current_trajectory_frame_set_input_file_pos, SEEK_SET); stat = tng_block_header_read(tng_data, block); - while(file_pos < tng_data->input_file_len && - stat != TNG_CRITICAL && - block->id != TNG_TRAJECTORY_FRAME_SET && - block->id != -1) + if(stat != TNG_SUCCESS) { - /* Use hash by default */ - stat = tng_block_read_next(tng_data, block, - TNG_USE_HASH); - if(stat != TNG_CRITICAL) - { - file_pos = ftello(tng_data->input_file); - if(file_pos < tng_data->input_file_len) - { - stat = tng_block_header_read(tng_data, block); - } - } + tng_block_destroy(&block); + return(stat); } - tng_block_destroy(&block); - if(stat == TNG_CRITICAL) + } + if(block->id == TNG_TRAJECTORY_FRAME_SET) + { + stat = tng_block_read_next(tng_data, block, TNG_SKIP_HASH); + if(stat != TNG_SUCCESS) { - fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", - file_pos, __FILE__, __LINE__); + tng_block_destroy(&block); return(stat); } - - for(i = 0; i < frame_set->n_data_blocks; i++) + stat = tng_block_header_read(tng_data, block); + } + while(stat == TNG_SUCCESS && block->id != TNG_TRAJECTORY_FRAME_SET && found == TNG_FALSE) + { + if(block->id == block_id) { - data = &frame_set->tr_data[i]; - if(data->block_id == block_id) + stat = tng_data_block_meta_information_read(tng_data, &datatype, + &dependency, &sparse_data, + &n_values, &codec_id, + &first_frame_with_data, + &stride_length, &curr_n_frames, + &num_first_particle, + &block_n_particles, + &multiplier, TNG_SKIP_HASH, + &md5_state); + if(stat == TNG_SUCCESS) { - block_index = i; - break; + found = TNG_TRUE; } } - if(block_index < 0) + else { - return(TNG_FAILURE); + fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR); + stat = tng_block_header_read(tng_data, block); } } + if(found == TNG_TRUE) + { + *n_frames = (tng_data->current_trajectory_frame_set.n_frames - + (tng_data->current_trajectory_frame_set.first_frame - first_frame_with_data)) / stride_length; + } + else if(stat == TNG_SUCCESS) + { + *n_frames = 0; + } - *n_frames = tng_max_i64(1, data->n_frames); - *n_values_per_frame = data->n_values_per_frame; - *type = data->datatype; + tng_block_destroy(&block); - if(*values == 0) + return(stat); +} + +static tng_function_status tng_frame_gen_data_write + (const tng_trajectory_t tng_data, + const int64_t frame_nr, + const int64_t block_id, + const tng_bool is_particle_data, + const int64_t val_first_particle, + const int64_t val_n_particles, + const void *values, + const char hash_mode) +{ + int64_t header_pos, file_pos, tot_n_particles; + int64_t output_file_len, n_values_per_frame, size, contents_size; + int64_t header_size, temp_first, temp_last; + int64_t mapping_block_end_pos, num_first_particle, block_n_particles; + int64_t i, last_frame, temp_current, write_n_particles; + tng_gen_block_t block; + tng_trajectory_frame_set_t frame_set; + FILE *temp = tng_data->input_file; + struct tng_data data; + tng_function_status stat; + tng_particle_mapping_t mapping; + char dependency, sparse_data, datatype; + void *copy; + + if(tng_output_file_init(tng_data) != TNG_SUCCESS) { - if(tng_data_values_alloc(tng_data, values, *n_frames, - *n_values_per_frame, - *type) - != TNG_SUCCESS) - { - return(TNG_CRITICAL); - } + fprintf(stderr, "TNG library: Cannot initialise destination file. %s: %d\n", + __FILE__, __LINE__); + return(TNG_CRITICAL); } - switch(*type) + temp_first = tng_data->first_trajectory_frame_set_input_file_pos; + temp_last = tng_data->last_trajectory_frame_set_input_file_pos; + temp_current = tng_data->current_trajectory_frame_set_input_file_pos; + tng_data->first_trajectory_frame_set_input_file_pos = + tng_data->first_trajectory_frame_set_output_file_pos; + tng_data->last_trajectory_frame_set_input_file_pos = + tng_data->last_trajectory_frame_set_output_file_pos; + tng_data->current_trajectory_frame_set_input_file_pos = + tng_data->current_trajectory_frame_set_output_file_pos; + + tng_data->input_file = tng_data->output_file; + + stat = tng_frame_set_of_frame_find(tng_data, frame_nr); + + frame_set = &tng_data->current_trajectory_frame_set; + + if(stat != TNG_SUCCESS) { - case TNG_CHAR_DATA: - for(i = 0; i < *n_frames; i++) + last_frame = frame_set->first_frame + + frame_set->n_frames - 1; + /* If the wanted frame would be in the frame set after the last + * frame set create a new frame set. */ + if(stat == TNG_FAILURE && + last_frame < frame_nr) +/* (last_frame < frame_nr && + tng_data->current_trajectory_frame_set.first_frame + + tng_data->frame_set_n_frames >= frame_nr))*/ { - for(j = 0; j < *n_values_per_frame; j++) + if(last_frame + tng_data->frame_set_n_frames < frame_nr) { - len = strlen(data->strings[i][j]) + 1; - (*values)[i][j].c = malloc(len); - strncpy((*values)[i][j].c, data->strings[i][j], len); + last_frame = frame_nr - 1; } - } - break; - case TNG_INT_DATA: - size = sizeof(int); - for(i = 0; i < *n_frames; i++) - { - for(j = 0; j < *n_values_per_frame; j++) + tng_frame_set_new(tng_data, + last_frame+1, + tng_data->frame_set_n_frames); + file_pos = ftello(tng_data->output_file); + fseeko(tng_data->output_file, 0, SEEK_END); + output_file_len = ftello(tng_data->output_file); + fseeko(tng_data->output_file, file_pos, SEEK_SET); + + /* Read mapping blocks from the last frame set */ + tng_block_init(&block); + + stat = tng_block_header_read(tng_data, block); + while(file_pos < output_file_len && + stat != TNG_CRITICAL && + block->id != TNG_TRAJECTORY_FRAME_SET && + block->id != -1) { - (*values)[i][j].i = *(int *)((char *)data->values + size * - (i*(*n_values_per_frame) + j)); + if(block->id == TNG_PARTICLE_MAPPING) + { + tng_trajectory_mapping_block_read(tng_data, block, + hash_mode); + } + else + { + fseeko(tng_data->output_file, block->block_contents_size, + SEEK_CUR); + } + file_pos = ftello(tng_data->output_file); + if(file_pos < output_file_len) + { + stat = tng_block_header_read(tng_data, block); + } } - } - break; - case TNG_FLOAT_DATA: - size = sizeof(float); - for(i = 0; i < *n_frames; i++) - { - for(j = 0; j < *n_values_per_frame; j++) + + tng_block_destroy(&block); + /* Write the frame set to disk */ + if(tng_frame_set_write(tng_data, hash_mode) != TNG_SUCCESS) { - (*values)[i][j].f = *(float *)((char *)data->values + size * - (i*(*n_values_per_frame) + j)); + fprintf(stderr, "TNG library: Error writing frame set. %s: %d\n", __FILE__, __LINE__); + return(TNG_CRITICAL); } } - break; - case TNG_DOUBLE_DATA: - default: - size = sizeof(double); - for(i = 0; i < *n_frames; i++) + else { - for(j = 0; j < *n_values_per_frame; j++) - { - (*values)[i][j].d = *(double *)((char *)data->values + size * - (i*(*n_values_per_frame) + j)); - } + tng_data->input_file = temp; + tng_data->first_trajectory_frame_set_input_file_pos = temp_first; + tng_data->last_trajectory_frame_set_input_file_pos = temp_last; + tng_data->current_trajectory_frame_set_input_file_pos = temp_current; + return(stat); } } - data->last_retrieved_frame = frame_set->first_frame + data->n_frames - 1; - - return(TNG_SUCCESS); -} + tng_block_init(&block); -tng_function_status tng_data_vector_get(tng_trajectory_t tng_data, - const int64_t block_id, - void **values, - int64_t *n_frames, - int64_t *stride_length, - int64_t *n_values_per_frame, - char *type) -{ - int64_t file_pos, data_size, n_frames_div, block_index; - int i, size; - tng_non_particle_data_t data; - tng_trajectory_frame_set_t frame_set; - tng_gen_block_t block; - void *temp; - tng_function_status stat; + file_pos = tng_data->current_trajectory_frame_set_output_file_pos; - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(n_frames, "TNG library: n_frames must not be a NULL pointer."); - TNG_ASSERT(stride_length, "TNG library: stride_length must not be a NULL pointer."); - TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); - TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); + fseeko(tng_data->output_file, 0, SEEK_END); + output_file_len = ftello(tng_data->output_file); + fseeko(tng_data->output_file, file_pos, SEEK_SET); - frame_set = &tng_data->current_trajectory_frame_set; + /* Read past the frame set block first */ + stat = tng_block_header_read(tng_data, block); + if(stat == TNG_CRITICAL) + { + fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", + file_pos, __FILE__, __LINE__); + tng_block_destroy(&block); + tng_data->input_file = temp; - block_index = -1; - data = 0; + tng_data->first_trajectory_frame_set_input_file_pos = temp_first; + tng_data->last_trajectory_frame_set_input_file_pos = temp_last; + tng_data->current_trajectory_frame_set_input_file_pos = temp_current; + return(stat); + } + fseeko(tng_data->output_file, block->block_contents_size, + SEEK_CUR); - if(tng_data_find(tng_data, block_id, &data) != TNG_SUCCESS) + if(is_particle_data == TNG_TRUE) { - tng_block_init(&block); - file_pos = ftello(tng_data->input_file); - /* Read all blocks until next frame set block */ - stat = tng_block_header_read(tng_data, block); - while(file_pos < tng_data->input_file_len && - stat != TNG_CRITICAL && - block->id != TNG_TRAJECTORY_FRAME_SET && - block->id != -1) + if(tng_data->var_num_atoms_flag) { - /* Use hash by default */ - stat = tng_block_read_next(tng_data, block, - TNG_USE_HASH); - if(stat != TNG_CRITICAL) + tot_n_particles = frame_set->n_particles; + } + else + { + tot_n_particles = tng_data->n_particles; + } + + if(val_n_particles < tot_n_particles) + { + mapping_block_end_pos = -1; + /* Read all mapping blocks to find the right place to put the data */ + stat = tng_block_header_read(tng_data, block); + while(file_pos < output_file_len && + stat != TNG_CRITICAL && + block->id != TNG_TRAJECTORY_FRAME_SET && + block->id != -1) { - file_pos = ftello(tng_data->input_file); - if(file_pos < tng_data->input_file_len) + if(block->id == TNG_PARTICLE_MAPPING) + { + tng_trajectory_mapping_block_read(tng_data, block, hash_mode); + } + else + { + fseeko(tng_data->output_file, block->block_contents_size, + SEEK_CUR); + } + file_pos = ftello(tng_data->output_file); + if(block->id == TNG_PARTICLE_MAPPING) + { + mapping = &frame_set->mappings[frame_set->n_mapping_blocks - 1]; + if(val_first_particle >= mapping->num_first_particle && + val_first_particle < mapping->num_first_particle + + mapping->n_particles && + val_first_particle + val_n_particles <= + mapping->num_first_particle + mapping->n_particles) + { + mapping_block_end_pos = file_pos; + } + } + if(file_pos < output_file_len) { stat = tng_block_header_read(tng_data, block); } } - } - tng_block_destroy(&block); - if(stat == TNG_CRITICAL) - { - fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", - file_pos, __FILE__, __LINE__); - return(stat); - } + if(stat == TNG_CRITICAL) + { + fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", + file_pos, __FILE__, __LINE__); + tng_block_destroy(&block); + tng_data->input_file = temp; - for(i = 0; i < frame_set->n_data_blocks; i++) - { - data = &frame_set->tr_data[i]; - if(data->block_id == block_id) + tng_data->first_trajectory_frame_set_input_file_pos = temp_first; + tng_data->last_trajectory_frame_set_input_file_pos = temp_last; + tng_data->current_trajectory_frame_set_input_file_pos = temp_current; + return(stat); + } + if(mapping_block_end_pos < 0) { - block_index = i; - break; + tng_block_destroy(&block); + tng_data->input_file = temp; + + tng_data->first_trajectory_frame_set_input_file_pos = temp_first; + tng_data->last_trajectory_frame_set_input_file_pos = temp_last; + tng_data->current_trajectory_frame_set_input_file_pos = temp_current; + return(TNG_FAILURE); } + fseeko(tng_data->output_file, mapping_block_end_pos, SEEK_SET); } - if(block_index < 0) + } + + /* Read all block headers until next frame set block or + * until the wanted block id is found */ + stat = tng_block_header_read(tng_data, block); + while(file_pos < output_file_len && + stat != TNG_CRITICAL && + block->id != block_id && + (is_particle_data != TNG_TRUE || block->id != TNG_PARTICLE_MAPPING) && + block->id != TNG_TRAJECTORY_FRAME_SET && + block->id != -1) + { + fseeko(tng_data->output_file, block->block_contents_size, SEEK_CUR); + file_pos = ftello(tng_data->output_file); + if(file_pos < output_file_len) { - return(TNG_FAILURE); + stat = tng_block_header_read(tng_data, block); } } - - *type = data->datatype; - - switch(*type) + if(stat == TNG_CRITICAL) { - case TNG_CHAR_DATA: - return(TNG_FAILURE); - case TNG_INT_DATA: - size = sizeof(int64_t); - break; - case TNG_FLOAT_DATA: - size = sizeof(float); - break; - case TNG_DOUBLE_DATA: - default: - size = sizeof(double); + fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", + file_pos, __FILE__, __LINE__); + tng_block_destroy(&block); + tng_data->input_file = temp; + tng_data->first_trajectory_frame_set_input_file_pos = temp_first; + tng_data->last_trajectory_frame_set_input_file_pos = temp_last; + tng_data->current_trajectory_frame_set_input_file_pos = temp_current; + return(stat); } - *n_frames = data->n_frames; - *n_values_per_frame = data->n_values_per_frame; - *stride_length = data->stride_length; - n_frames_div = (*n_frames % *stride_length) ? *n_frames / *stride_length + 1: - *n_frames / *stride_length; + contents_size = block->block_contents_size; + header_size = block->header_contents_size; - data_size = n_frames_div * size * - *n_values_per_frame; + header_pos = ftello(tng_data->output_file) - header_size; + frame_set = &tng_data->current_trajectory_frame_set; - temp = realloc(*values, data_size); - if(!temp) + if(tng_file_input_numerical(tng_data, &datatype, + sizeof(datatype), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - data_size, __FILE__, __LINE__); - free(*values); - *values = 0; + tng_block_destroy(&block); return(TNG_CRITICAL); } + if(tng_file_input_numerical(tng_data, &dependency, + sizeof(dependency), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) + { + tng_block_destroy(&block); + return(TNG_CRITICAL); + } + data.datatype = datatype; - *values = temp; - - memcpy(*values, data->values, data_size); - - data->last_retrieved_frame = frame_set->first_frame + data->n_frames - 1; - - return(TNG_SUCCESS); -} + if(!(dependency & TNG_FRAME_DEPENDENT) || + (is_particle_data == TNG_FALSE && dependency & TNG_PARTICLE_DEPENDENT) || + (is_particle_data == TNG_TRUE && !(dependency & TNG_PARTICLE_DEPENDENT))) + { + tng_block_destroy(&block); + tng_data->input_file = temp; -tng_function_status DECLSPECDLLEXPORT tng_data_interval_get - (tng_trajectory_t tng_data, - const int64_t block_id, - const int64_t start_frame_nr, - const int64_t end_frame_nr, - const char hash_mode, - union data_values ***values, - int64_t *n_values_per_frame, - char *type) -{ - int64_t i, j, n_frames, file_pos, current_frame_pos, first_frame; - int64_t block_index; - int size; - size_t len; - tng_non_particle_data_t data; - tng_trajectory_frame_set_t frame_set; - tng_gen_block_t block; - tng_function_status stat; + tng_data->first_trajectory_frame_set_input_file_pos = temp_first; + tng_data->last_trajectory_frame_set_input_file_pos = temp_last; + tng_data->current_trajectory_frame_set_input_file_pos = temp_current; + return(TNG_FAILURE); + } - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(start_frame_nr <= end_frame_nr, "TNG library: start_frame_nr must not be higher than tne end_frame_nr."); - TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); - TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); + if(tng_file_input_numerical(tng_data, &sparse_data, + sizeof(sparse_data), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) + { + tng_block_destroy(&block); + return(TNG_CRITICAL); + } - block_index = -1; + if(tng_file_input_numerical(tng_data, &data.n_values_per_frame, + sizeof(data.n_values_per_frame), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) + { + tng_block_destroy(&block); + return(TNG_CRITICAL); + } - frame_set = &tng_data->current_trajectory_frame_set; - first_frame = frame_set->first_frame; + if(tng_file_input_numerical(tng_data, &data.codec_id, + sizeof(data.codec_id), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) + { + tng_block_destroy(&block); + return(TNG_CRITICAL); + } - stat = tng_frame_set_of_frame_find(tng_data, start_frame_nr); - if(stat != TNG_SUCCESS) + if(data.codec_id != TNG_UNCOMPRESSED) { - return(stat); + if(tng_file_input_numerical(tng_data, &data.compression_multiplier, + sizeof(data.compression_multiplier), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) + { + tng_block_destroy(&block); + return(TNG_CRITICAL); + } + } + else + { + data.compression_multiplier = 1; } + if(sparse_data) + { + if(tng_file_input_numerical(tng_data, &data.first_frame_with_data, + sizeof(data.first_frame_with_data), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) + { + tng_block_destroy(&block); + return(TNG_CRITICAL); + } - /* Do not re-read the frame set. */ - if(first_frame != frame_set->first_frame || - frame_set->n_data_blocks <= 0) + if(tng_file_input_numerical(tng_data, &data.stride_length, + sizeof(data.stride_length), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) + { + tng_block_destroy(&block); + return(TNG_CRITICAL); + } + } + else + { + data.first_frame_with_data = 0; + data.stride_length = 1; + } + data.n_frames = tng_data->current_trajectory_frame_set.n_frames; + + if(is_particle_data == TNG_TRUE) { - tng_block_init(&block); - file_pos = ftello(tng_data->input_file); - /* Read all blocks until next frame set block */ - stat = tng_block_header_read(tng_data, block); - while(file_pos < tng_data->input_file_len && - stat != TNG_CRITICAL && - block->id != TNG_TRAJECTORY_FRAME_SET && - block->id != -1) + if(tng_file_input_numerical(tng_data, &num_first_particle, + sizeof(num_first_particle), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) { - stat = tng_block_read_next(tng_data, block, - hash_mode); - if(stat != TNG_CRITICAL) - { - file_pos = ftello(tng_data->input_file); - if(file_pos < tng_data->input_file_len) - { - stat = tng_block_header_read(tng_data, block); - } - } + tng_block_destroy(&block); + return(TNG_CRITICAL); } - tng_block_destroy(&block); - if(stat == TNG_CRITICAL) + + if(tng_file_input_numerical(tng_data, &block_n_particles, + sizeof(block_n_particles), + TNG_SKIP_HASH, 0, __LINE__) == TNG_CRITICAL) { - fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", - file_pos, __FILE__, __LINE__); - return(stat); + tng_block_destroy(&block); + return(TNG_CRITICAL); } } + tng_data->input_file = temp; - /* See if there is a data block of this ID. - * Start checking the last read frame set */ - for(i = 0; i < frame_set->n_data_blocks; i++) + tng_data->first_trajectory_frame_set_input_file_pos = temp_first; + tng_data->last_trajectory_frame_set_input_file_pos = temp_last; + tng_data->current_trajectory_frame_set_input_file_pos = temp_current; + + switch(data.datatype) { - data = &frame_set->tr_data[i]; - if(data->block_id == block_id) - { - block_index = i; + case(TNG_INT_DATA): + size = sizeof(int64_t); break; - } + case(TNG_FLOAT_DATA): + size = sizeof(float); + break; + case(TNG_DOUBLE_DATA): + size = sizeof(double); + break; + default: + fprintf(stderr, "TNG library: Cannot calculate writing locations. %s: %d.\n", __FILE__, + __LINE__); + tng_block_destroy(&block); + return(TNG_FAILURE); } - if(block_index < 0) + n_values_per_frame = data.n_values_per_frame; + + file_pos = (frame_nr - tng_max_i64(frame_set->first_frame, + data.first_frame_with_data)) / + data.stride_length; + if(is_particle_data == TNG_TRUE) { - fprintf(stderr, "TNG library: Could not find non-particle data block with id %"PRId64". %s: %d\n", - block_id, __FILE__, __LINE__); + file_pos *= block_n_particles * size * n_values_per_frame; + } + else + { + file_pos *= size * n_values_per_frame; + } + + if(file_pos > contents_size) + { + fprintf(stderr, "TNG library: Attempting to write outside the block. %s: %d\n", __FILE__, + __LINE__); + tng_block_destroy(&block); return(TNG_FAILURE); } - n_frames = end_frame_nr - start_frame_nr + 1; - *n_values_per_frame = data->n_values_per_frame; - *type = data->datatype; + fseeko(tng_data->output_file, file_pos, SEEK_CUR); - if(*values == 0) + if(is_particle_data == TNG_TRUE) { - if(tng_data_values_alloc(tng_data, values, n_frames, - *n_values_per_frame, - *type) != TNG_SUCCESS) - { - return(TNG_CRITICAL); - } + write_n_particles = val_n_particles; + } + else + { + write_n_particles = 1; } - current_frame_pos = start_frame_nr - frame_set->first_frame; - /* It's not very elegant to reuse so much of the code in the different case - * statements, but it's unnecessarily slow to have the switch-case block - * inside the for loops. */ - switch(*type) + /* If the endianness is not big endian the data needs to be swapped */ + if((data.datatype == TNG_INT_DATA || + data.datatype == TNG_DOUBLE_DATA) && + tng_data->output_endianness_swap_func_64) { - case TNG_CHAR_DATA: - for(i=0; in_frames) - { - stat = tng_frame_set_read_next(tng_data, hash_mode); - if(stat != TNG_SUCCESS) - { - return(stat); - } - current_frame_pos = 0; - } - for(j = 0; j < *n_values_per_frame; j++) - { - len = strlen(data->strings[current_frame_pos][j]) + 1; - (*values)[i][j].c = malloc(len); - strncpy((*values)[i][j].c, data->strings[current_frame_pos][j], len); - } - current_frame_pos++; - } - break; - case TNG_INT_DATA: - size = sizeof(int); - for(i=0; in_frames) - { - stat = tng_frame_set_read_next(tng_data, hash_mode); - if(stat != TNG_SUCCESS) - { - return(stat); - } - current_frame_pos = 0; - } - for(j = 0; j < *n_values_per_frame; j++) - { - (*values)[i][j].i = *(int *)((char *)data->values + size * - (current_frame_pos * - (*n_values_per_frame) + j)); - } - current_frame_pos++; - } - break; - case TNG_FLOAT_DATA: - size = sizeof(float); - for(i=0; in_frames) - { - stat = tng_frame_set_read_next(tng_data, hash_mode); - if(stat != TNG_SUCCESS) - { - return(stat); - } - current_frame_pos = 0; - } - for(j = 0; j < *n_values_per_frame; j++) + if(tng_data->output_endianness_swap_func_64(tng_data, + (int64_t *) copy+i) + != TNG_SUCCESS) { - (*values)[i][j].f = *(float *)((char *)data->values + size * - (current_frame_pos * - (*n_values_per_frame) + j)); + fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); } - current_frame_pos++; } - break; - case TNG_DOUBLE_DATA: - default: - size = sizeof(double); - for(i=0; ioutput_file); + free(copy); + } + else if(data.datatype == TNG_FLOAT_DATA && + tng_data->output_endianness_swap_func_32) + { + copy = malloc(write_n_particles * n_values_per_frame * size); + memcpy(copy, values, write_n_particles * n_values_per_frame * size); + for(i = 0; i < write_n_particles * n_values_per_frame; i++) { - if(current_frame_pos == frame_set->n_frames) - { - stat = tng_frame_set_read_next(tng_data, hash_mode); - if(stat != TNG_SUCCESS) - { - return(stat); - } - current_frame_pos = 0; - } - for(j = 0; j < *n_values_per_frame; j++) + if(tng_data->output_endianness_swap_func_32(tng_data, + (int32_t *) copy+i) + != TNG_SUCCESS) { - (*values)[i][j].d = *(double *)((char *)data->values + size * - (current_frame_pos * - (*n_values_per_frame) + j)); + fprintf(stderr, "TNG library: Cannot swap byte order. %s: %d\n", + __FILE__, __LINE__); } - current_frame_pos++; } + fwrite(copy, write_n_particles * n_values_per_frame, size, + tng_data->output_file); + free(copy); } - data->last_retrieved_frame = end_frame_nr; + else + { + fwrite(values, write_n_particles * n_values_per_frame, size, tng_data->output_file); + } + + fflush(tng_data->output_file); + + /* Update the number of written frames in the frame set. */ + if(frame_nr - frame_set->first_frame + 1 > frame_set->n_written_frames) + { + frame_set->n_written_frames = frame_nr - frame_set->first_frame + 1; + } + + /* If the last frame has been written update the hash */ + if(hash_mode == TNG_USE_HASH && (frame_nr + data.stride_length - + data.first_frame_with_data) >= + frame_set->n_frames) + { + tng_md5_hash_update(tng_data, block, header_pos, header_pos + + header_size); + } + + tng_block_destroy(&block); return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_data_vector_interval_get - (tng_trajectory_t tng_data, +tng_function_status DECLSPECDLLEXPORT tng_frame_data_write + (const tng_trajectory_t tng_data, + const int64_t frame_nr, const int64_t block_id, - const int64_t start_frame_nr, - const int64_t end_frame_nr, - const char hash_mode, - void **values, - int64_t *stride_length, - int64_t *n_values_per_frame, - char *type) + const void *values, + const char hash_mode) { - int64_t n_frames, tot_n_frames, n_frames_div, n_frames_div_2, first_frame; - int64_t file_pos, current_frame_pos, data_size, frame_size; - int64_t last_frame_pos; - int size; - tng_trajectory_frame_set_t frame_set; - tng_non_particle_data_t np_data; - tng_gen_block_t block; - void *current_values = 0, *temp; - tng_function_status stat; + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(frame_nr >= 0, "TNG library: frame_nr must be >= 0."); + TNG_ASSERT(values, "TNG library: values must not be a NULL pointer."); + + /* This is now just calling the generic data writing function. This + * function must keep its signature to let the API be backwards + * compatible. */ + return(tng_frame_gen_data_write(tng_data, frame_nr, block_id, + TNG_FALSE, 0, 0, values, hash_mode)); +} +tng_function_status DECLSPECDLLEXPORT tng_frame_particle_data_write + (const tng_trajectory_t tng_data, + const int64_t frame_nr, + const int64_t block_id, + const int64_t val_first_particle, + const int64_t val_n_particles, + const void *values, + const char hash_mode) +{ TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(start_frame_nr <= end_frame_nr, "TNG library: start_frame_nr must not be higher than the end_frame_nr."); - TNG_ASSERT(stride_length, "TNG library: stride_length must not be a NULL pointer."); - TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); - TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); + TNG_ASSERT(frame_nr >= 0, "TNG library: frame_nr must be >= 0."); + TNG_ASSERT(values, "TNG library: values must not be a NULL pointer."); + TNG_ASSERT(val_first_particle >= 0, "TNG library: val_first_particle must be >= 0."); + TNG_ASSERT(val_n_particles >= 0, "TNG library: val_n_particles must be >= 0."); - frame_set = &tng_data->current_trajectory_frame_set; - first_frame = frame_set->first_frame; + /* This is now just calling the generic data writing function. This + * function must keep its signature to let the API be backwards + * compatible. */ + return(tng_frame_gen_data_write(tng_data, frame_nr, block_id, + TNG_TRUE, val_first_particle, val_n_particles, + values, hash_mode)); +} - stat = tng_frame_set_of_frame_find(tng_data, start_frame_nr); - if(stat != TNG_SUCCESS) +static tng_function_status tng_data_values_alloc + (const tng_trajectory_t tng_data, + union data_values ***values, + const int64_t n_frames, + const int64_t n_values_per_frame, + const char type) +{ + int64_t i; + tng_function_status stat; + + if(n_frames <= 0 || n_values_per_frame <= 0) { - return(stat); + return(TNG_FAILURE); } - /* Do not re-read the frame set and only need the requested block. */ - /* TODO: Test that blocks are read correctly now that not all of them are read at the same time. */ - stat = tng_data_find(tng_data, block_id, &np_data); - if(first_frame != frame_set->first_frame || - stat != TNG_SUCCESS) + if(*values) { - tng_block_init(&block); + stat = tng_data_values_free(tng_data, *values, n_frames, + n_values_per_frame, + type); if(stat != TNG_SUCCESS) { - fseeko(tng_data->input_file, - tng_data->current_trajectory_frame_set_input_file_pos, - SEEK_SET); - stat = tng_block_header_read(tng_data, block); - if(stat != TNG_SUCCESS) - { - fprintf(stderr, "TNG library: Cannot read block header. %s: %d\n", - __FILE__, __LINE__); - return(stat); - } - - fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR); - } - file_pos = ftello(tng_data->input_file); - /* Read until next frame set block */ - stat = tng_block_header_read(tng_data, block); - while(file_pos < tng_data->input_file_len && - stat != TNG_CRITICAL && - block->id != TNG_TRAJECTORY_FRAME_SET && - block->id != -1) - { - if(block->id == block_id) - { - stat = tng_block_read_next(tng_data, block, - hash_mode); - if(stat != TNG_CRITICAL) - { - file_pos = ftello(tng_data->input_file); - if(file_pos < tng_data->input_file_len) - { - stat = tng_block_header_read(tng_data, block); - } - } - } - else - { - file_pos += block->block_contents_size + block->header_contents_size; - fseeko(tng_data->input_file, block->block_contents_size, SEEK_CUR); - if(file_pos < tng_data->input_file_len) - { - stat = tng_block_header_read(tng_data, block); - } - } - } - tng_block_destroy(&block); - if(stat == TNG_CRITICAL) - { - fprintf(stderr, "TNG library: Cannot read block header at pos %"PRId64". %s: %d\n", - file_pos, __FILE__, __LINE__); + fprintf(stderr, "TNG library: Cannot free particle data values. %s: %d\n", + __FILE__, __LINE__); return(stat); } } - - stat = tng_data_find(tng_data, block_id, &np_data); - if(stat != TNG_SUCCESS) + *values = malloc(sizeof(union data_values *) * n_frames); + if(!*values) { - return(stat); - } + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", + sizeof(union data_values **) * n_frames, + __FILE__, __LINE__); + return(TNG_CRITICAL); - stat = tng_data_vector_get(tng_data, block_id, ¤t_values, - &n_frames, stride_length, - n_values_per_frame, type); + } - if(stat != TNG_SUCCESS) + for(i = 0; i < n_frames; i++) { - if(current_values) + (*values)[i] = malloc(sizeof(union data_values) * + n_values_per_frame); + if(!(*values)[i]) { - free(current_values); + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", + sizeof(union data_values) * n_values_per_frame, + __FILE__, __LINE__); + free(values); + values = 0; + return(TNG_CRITICAL); } - return(stat); } + return(TNG_SUCCESS); +} - if(n_frames == 1 && n_frames < frame_set->n_frames) - { - tot_n_frames = 1; - } - else - { - tot_n_frames = end_frame_nr - start_frame_nr + 1; - } +/* FIXME: This needs ***values */ +tng_function_status DECLSPECDLLEXPORT tng_data_values_free + (const tng_trajectory_t tng_data, + union data_values **values, + const int64_t n_frames, + const int64_t n_values_per_frame, + const char type) +{ + int64_t i, j; + (void)tng_data; - switch(*type) + if(values) { - case TNG_CHAR_DATA: - return(TNG_FAILURE); - case TNG_INT_DATA: - size = sizeof(int64_t); - break; - case TNG_FLOAT_DATA: - size = sizeof(float); - break; - case TNG_DOUBLE_DATA: - default: - size = sizeof(double); + for(i = 0; i < n_frames; i++) + { + if(values[i]) + { + if(type == TNG_CHAR_DATA) + { + for(j = 0; j < n_values_per_frame; j++) + { + if(values[i][j].c) + { + free(values[i][j].c); + values[i][j].c = 0; + } + } + } + free(values[i]); + values[i] = 0; + } + } + free(values); + values = 0; } - n_frames_div = (tot_n_frames % *stride_length) ? - tot_n_frames / *stride_length + 1: - tot_n_frames / *stride_length; - data_size = n_frames_div * size * (*n_values_per_frame); + return(TNG_SUCCESS); +} -/* fprintf(stderr, "TNG library: size: %d, n_frames_div: %"PRId64", data_size: %"PRId64"\n", - size, n_frames_div, data_size); -*/ - temp = realloc(*values, data_size); - if(!temp) +static tng_function_status tng_particle_data_values_alloc + (const tng_trajectory_t tng_data, + union data_values ****values, + const int64_t n_frames, + const int64_t n_particles, + const int64_t n_values_per_frame, + const char type) +{ + int64_t i, j; + tng_function_status stat; + + if(n_particles == 0 || n_values_per_frame == 0) { - fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - data_size, __FILE__, __LINE__); - free(*values); - *values = 0; - return(TNG_CRITICAL); + return(TNG_FAILURE); } - *values = temp; - - if( n_frames == 1 && n_frames < frame_set->n_frames) + if(*values) { - memcpy(*values, current_values, size * (*n_values_per_frame)); + stat = tng_particle_data_values_free(tng_data, *values, n_frames, + n_particles, n_values_per_frame, + type); + if(stat != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Cannot free particle data values. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } } - else + *values = malloc(sizeof(union data_values **) * n_frames); + if(!*values) { - current_frame_pos = start_frame_nr - frame_set->first_frame; - - frame_size = size * (*n_values_per_frame); - - last_frame_pos = tng_min_i64(n_frames, - end_frame_nr - start_frame_nr); - - n_frames_div = current_frame_pos / *stride_length; - n_frames_div_2 = (last_frame_pos % *stride_length) ? - last_frame_pos / *stride_length + 1: - last_frame_pos / *stride_length; - n_frames_div_2 = tng_max_i64(1, n_frames_div_2); - - memcpy(*values, (char *)current_values + n_frames_div * frame_size, - n_frames_div_2 * frame_size); + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", + sizeof(union data_values **) * n_frames, + __FILE__, __LINE__); + return(TNG_CRITICAL); - current_frame_pos += n_frames - current_frame_pos; + } - while(current_frame_pos <= end_frame_nr - start_frame_nr) + for(i = 0; i < n_frames; i++) + { + (*values)[i] = malloc(sizeof(union data_values *) * + n_particles); + if(!(*values)[i]) { - stat = tng_frame_set_read_next(tng_data, hash_mode); - if(stat != TNG_SUCCESS) + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", + sizeof(union data_values *) * n_particles, + __FILE__, __LINE__); + free(*values); + *values = 0; + return(TNG_CRITICAL); + } + for(j = 0; j < n_particles; j++) + { + (*values)[i][j] = malloc(sizeof(union data_values) * + n_values_per_frame); + if(!(*values)[i][j]) { - if(current_values) - { - free(current_values); - } - free(*values); + fprintf(stderr, "TNG library: Cannot allocate memory (%"PRIu64" bytes). %s: %d\n", + sizeof(union data_values *) * n_particles, + __FILE__, __LINE__); + tng_particle_data_values_free(tng_data, *values, n_frames, + n_particles, n_values_per_frame, + type); *values = 0; - return(stat); + return(TNG_CRITICAL); } + } + } + return(TNG_SUCCESS); +} - stat = tng_data_vector_get(tng_data, block_id, ¤t_values, - &n_frames, stride_length, - n_values_per_frame, type); +/* FIXME: This needs ****values */ +tng_function_status DECLSPECDLLEXPORT tng_particle_data_values_free + (const tng_trajectory_t tng_data, + union data_values ***values, + const int64_t n_frames, + const int64_t n_particles, + const int64_t n_values_per_frame, + const char type) +{ + int64_t i, j, k; + (void)tng_data; - if(stat != TNG_SUCCESS) + if(values) + { + for(i = 0; i < n_frames; i++) + { + if(values[i]) { - if(current_values) + for(j = 0; j < n_particles; j++) { - free(current_values); + if(type == TNG_CHAR_DATA) + { + for(k = 0; k < n_values_per_frame; k++) + { + if(values[i][j][k].c) + { + free(values[i][j][k].c); + values[i][j][k].c = 0; + } + } + } + free(values[i][j]); + values[i][j] = 0; } - free(*values); - *values = 0; - return(stat); + free(values[i]); + values[i] = 0; } - - last_frame_pos = tng_min_i64(n_frames, - end_frame_nr - current_frame_pos); - - n_frames_div = current_frame_pos / *stride_length; - n_frames_div_2 = (last_frame_pos % *stride_length) ? - last_frame_pos / *stride_length + 1: - last_frame_pos / *stride_length; - n_frames_div_2 = tng_max_i64(1, n_frames_div_2); - - memcpy(((char *)*values) + n_frames_div * frame_size, - current_values, - n_frames_div_2 * frame_size); - - current_frame_pos += n_frames; } + free(values); + values = 0; } - if(current_values) - { - free(current_values); - } - - np_data->last_retrieved_frame = end_frame_nr; - return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_particle_data_get - (tng_trajectory_t tng_data, +static tng_function_status tng_gen_data_get + (const tng_trajectory_t tng_data, const int64_t block_id, + const tng_bool is_particle_data, union data_values ****values, int64_t *n_frames, int64_t *n_particles, @@ -16007,34 +13876,37 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_get int64_t i, j, k, mapping, file_pos, i_step, block_index; int size; size_t len; - tng_particle_data_t data; + tng_data_t data; tng_trajectory_frame_set_t frame_set; tng_gen_block_t block; char block_type_flag; tng_function_status stat; - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(n_frames, "TNG library: n_frames must not be a NULL pointer."); - TNG_ASSERT(n_particles, "TNG library: n_particles must not be a NULL pointer."); - TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); - TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); - frame_set = &tng_data->current_trajectory_frame_set; block_index = -1; data = 0; - if(tng_particle_data_find(tng_data, block_id, &data) != TNG_SUCCESS) + if(is_particle_data == TNG_TRUE) { - if(tng_data->current_trajectory_frame_set_input_file_pos > 0) - { - block_type_flag = TNG_TRAJECTORY_BLOCK; - } - else - { - block_type_flag = TNG_NON_TRAJECTORY_BLOCK; - } + stat = tng_particle_data_find(tng_data, block_id, &data); + } + else + { + stat = tng_data_find(tng_data, block_id, &data); + } + + if(tng_data->current_trajectory_frame_set_input_file_pos > 0) + { + block_type_flag = TNG_TRAJECTORY_BLOCK; + } + else + { + block_type_flag = TNG_NON_TRAJECTORY_BLOCK; + } + if(stat != TNG_SUCCESS) + { tng_block_init(&block); file_pos = ftello(tng_data->input_file); /* Read all blocks until next frame set block */ @@ -16064,14 +13936,29 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_get return(stat); } - for(i = 0; i < frame_set->n_particle_data_blocks; i++) + if(is_particle_data == TNG_TRUE) { - data = &frame_set->tr_particle_data[i]; - if(data->block_id == block_id) + for(i = 0; i < frame_set->n_particle_data_blocks; i++) { - block_index = i; - block_type_flag = TNG_TRAJECTORY_BLOCK; - break; + data = &frame_set->tr_particle_data[i]; + if(data->block_id == block_id) + { + block_index = i; + block_type_flag = TNG_TRAJECTORY_BLOCK; + break; + } + } + } + else + { + for(i = 0; i < frame_set->n_data_blocks; i++) + { + data = &frame_set->tr_data[i]; + if(data->block_id == block_id) + { + block_index = i; + break; + } } } if(block_index < 0) @@ -16079,115 +13966,167 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_get return(TNG_FAILURE); } } - else + + if(is_particle_data == TNG_TRUE) { - if(tng_data->current_trajectory_frame_set_input_file_pos > 0) + if(block_type_flag == TNG_TRAJECTORY_BLOCK && + tng_data->var_num_atoms_flag) { - block_type_flag = TNG_TRAJECTORY_BLOCK; + *n_particles = frame_set->n_particles; } else { - block_type_flag = TNG_NON_TRAJECTORY_BLOCK; + *n_particles = tng_data->n_particles; } } - if(block_type_flag == TNG_TRAJECTORY_BLOCK && - tng_data->var_num_atoms_flag) - { - *n_particles = frame_set->n_particles; - } - else - { - *n_particles = tng_data->n_particles; - } - *n_frames = tng_max_i64(1, data->n_frames); *n_values_per_frame = data->n_values_per_frame; *type = data->datatype; - if(*values == 0) + if(is_particle_data == TNG_TRUE) { - if(tng_particle_data_values_alloc(tng_data, values, *n_frames, - *n_particles, *n_values_per_frame, - *type) - != TNG_SUCCESS) + if(*values == 0) { - return(TNG_CRITICAL); + if(tng_particle_data_values_alloc(tng_data, values, *n_frames, + *n_particles, *n_values_per_frame, + *type) != TNG_SUCCESS) + { + return(TNG_CRITICAL); + } } - } - /* It's not very elegant to reuse so much of the code in the different case - * statements, but it's unnecessarily slow to have the switch-case block - * inside the for loops. */ - switch(*type) - { - case TNG_CHAR_DATA: - for(i = 0; i < *n_frames; i++) + i_step = (*n_particles) * (*n_values_per_frame); + + /* It's not very elegant to reuse so much of the code in the different case + * statements, but it's unnecessarily slow to have the switch-case block + * inside the for loops. */ + switch(*type) { - for(j = 0; j < *n_particles; j++) + case TNG_CHAR_DATA: + for(i = 0; i < *n_frames; i++) { - tng_particle_mapping_get_real_particle(frame_set, j, &mapping); - for(k = 0; k < *n_values_per_frame; k++) + for(j = 0; j < *n_particles; j++) { - len = strlen(data->strings[i][j][k]) + 1; - (*values)[i][mapping][k].c = malloc(len); - strncpy((*values)[i][mapping][k].c, - data->strings[i][j][k], len); + tng_particle_mapping_get_real_particle(frame_set, j, &mapping); + for(k = 0; k < *n_values_per_frame; k++) + { + len = strlen(data->strings[i][j][k]) + 1; + (*values)[i][mapping][k].c = malloc(len); + strncpy((*values)[i][mapping][k].c, + data->strings[i][j][k], len); + } } } - } - break; - case TNG_INT_DATA: - size = sizeof(int); - i_step = (*n_particles) * (*n_values_per_frame); - for(i = 0; i < *n_frames; i++) - { - for(j = 0; j < *n_particles; j++) + break; + case TNG_INT_DATA: + size = sizeof(int); + for(i = 0; i < *n_frames; i++) { - tng_particle_mapping_get_real_particle(frame_set, j, &mapping); - for(k = 0; k < *n_values_per_frame; k++) + for(j = 0; j < *n_particles; j++) { - (*values)[i][mapping][k].i = *(int *) - ((char *)data->values + size * - (i * i_step + j * - (*n_values_per_frame) + k)); + tng_particle_mapping_get_real_particle(frame_set, j, &mapping); + for(k = 0; k < *n_values_per_frame; k++) + { + (*values)[i][mapping][k].i = *(int *) + ((char *)data->values + size * + (i * i_step + j * + (*n_values_per_frame) + k)); + } } } - } - break; - case TNG_FLOAT_DATA: - size = sizeof(float); - i_step = (*n_particles) * (*n_values_per_frame); - for(i = 0; i < *n_frames; i++) - { - for(j = 0; j < *n_particles; j++) + break; + case TNG_FLOAT_DATA: + size = sizeof(float); + for(i = 0; i < *n_frames; i++) { - tng_particle_mapping_get_real_particle(frame_set, j, &mapping); - for(k = 0; k < *n_values_per_frame; k++) + for(j = 0; j < *n_particles; j++) + { + tng_particle_mapping_get_real_particle(frame_set, j, &mapping); + for(k = 0; k < *n_values_per_frame; k++) + { + (*values)[i][mapping][k].f = *(float *) + ((char *)data->values + size * + (i * i_step + j * + (*n_values_per_frame) + k)); + } + } + } + break; + case TNG_DOUBLE_DATA: + default: + size = sizeof(double); + for(i = 0; i < *n_frames; i++) + { + for(j = 0; j < *n_particles; j++) { - (*values)[i][mapping][k].f = *(float *) - ((char *)data->values + size * - (i * i_step + j * - (*n_values_per_frame) + k)); + tng_particle_mapping_get_real_particle(frame_set, j, &mapping); + for(k = 0; k < *n_values_per_frame; k++) + { + (*values)[i][mapping][k].d = *(double *) + ((char *)data->values + size * + (i * i_step + j * + (*n_values_per_frame) + k)); + } } } } - break; - case TNG_DOUBLE_DATA: - default: - size = sizeof(double); - i_step = (*n_particles) * (*n_values_per_frame); - for(i = 0; i < *n_frames; i++) + } + else + { + if(*(values[0]) == 0) { - for(j = 0; j < *n_particles; j++) + if(tng_data_values_alloc(tng_data, values[0], *n_frames, + *n_values_per_frame, + *type) != TNG_SUCCESS) { - tng_particle_mapping_get_real_particle(frame_set, j, &mapping); - for(k = 0; k < *n_values_per_frame; k++) + return(TNG_CRITICAL); + } + } + switch(*type) + { + case TNG_CHAR_DATA: + for(i = 0; i < *n_frames; i++) + { + for(j = 0; j < *n_values_per_frame; j++) + { + len = strlen(data->strings[0][i][j]) + 1; + (*values)[0][i][j].c = malloc(len); + strncpy((*values)[0][i][j].c, data->strings[0][i][j], len); + } + } + break; + case TNG_INT_DATA: + size = sizeof(int); + for(i = 0; i < *n_frames; i++) + { + for(j = 0; j < *n_values_per_frame; j++) + { + (*values)[0][i][j].i = *(int *)((char *)data->values + size * + (i*(*n_values_per_frame) + j)); + } + } + break; + case TNG_FLOAT_DATA: + size = sizeof(float); + for(i = 0; i < *n_frames; i++) + { + for(j = 0; j < *n_values_per_frame; j++) + { + (*values)[0][i][j].f = *(float *)((char *)data->values + size * + (i*(*n_values_per_frame) + j)); + } + } + break; + case TNG_DOUBLE_DATA: + default: + size = sizeof(double); + for(i = 0; i < *n_frames; i++) + { + for(j = 0; j < *n_values_per_frame; j++) { - (*values)[i][mapping][k].d = *(double *) - ((char *)data->values + size * - (i * i_step + j * - (*n_values_per_frame) + k)); + (*values)[0][i][j].d = *(double *)((char *)data->values + size * + (i*(*n_values_per_frame) + j)); } } } @@ -16198,9 +14137,27 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_get return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_get - (tng_trajectory_t tng_data, +tng_function_status DECLSPECDLLEXPORT tng_data_get + (const tng_trajectory_t tng_data, + const int64_t block_id, + union data_values ***values, + int64_t *n_frames, + int64_t *n_values_per_frame, + char *type) +{ + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(n_frames, "TNG library: n_frames must not be a NULL pointer."); + TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); + TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); + + return(tng_gen_data_get(tng_data, block_id, TNG_FALSE, &values, n_frames, 0, + n_values_per_frame, type)); +} + +static tng_function_status tng_gen_data_vector_get + (const tng_trajectory_t tng_data, const int64_t block_id, + const tng_bool is_particle_data, void **values, int64_t *n_frames, int64_t *stride_length, @@ -16208,28 +14165,31 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_get int64_t *n_values_per_frame, char *type) { - int64_t i, j, mapping, file_pos, i_step, data_size, n_frames_div; + int64_t i, j, mapping, file_pos, i_step, full_data_len, n_frames_div; int64_t block_index; int size; - tng_particle_data_t data; + tng_data_t data; tng_trajectory_frame_set_t frame_set; tng_gen_block_t block; void *temp; char block_type_flag; tng_function_status stat; - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(n_particles, "TNG library: n_particles must not be a NULL pointer."); - TNG_ASSERT(stride_length, "TNG library: stride_length must not be a NULL pointer."); - TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); - TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); - frame_set = &tng_data->current_trajectory_frame_set; block_index = -1; data = 0; - if(tng_particle_data_find(tng_data, block_id, &data) != TNG_SUCCESS) + if(is_particle_data == TNG_TRUE) + { + stat = tng_particle_data_find(tng_data, block_id, &data); + } + else + { + stat = tng_data_find(tng_data, block_id, &data); + } + + if(stat != TNG_SUCCESS) { tng_block_init(&block); file_pos = ftello(tng_data->input_file); @@ -16275,23 +14235,26 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_get } } - if(tng_data->current_trajectory_frame_set_input_file_pos > 0) - { - block_type_flag = TNG_TRAJECTORY_BLOCK; - } - else + if(is_particle_data == TNG_TRUE) { - block_type_flag = TNG_NON_TRAJECTORY_BLOCK; - } + if(tng_data->current_trajectory_frame_set_input_file_pos > 0) + { + block_type_flag = TNG_TRAJECTORY_BLOCK; + } + else + { + block_type_flag = TNG_NON_TRAJECTORY_BLOCK; + } - if(block_type_flag == TNG_TRAJECTORY_BLOCK && - tng_data->var_num_atoms_flag) - { - *n_particles = frame_set->n_particles; - } - else - { - *n_particles = tng_data->n_particles; + if(block_type_flag == TNG_TRAJECTORY_BLOCK && + tng_data->var_num_atoms_flag) + { + *n_particles = frame_set->n_particles; + } + else + { + *n_particles = tng_data->n_particles; + } } *type = data->datatype; @@ -16319,14 +14282,18 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_get *n_frames / *stride_length + 1: *n_frames / *stride_length; - data_size = n_frames_div * size * (*n_particles) * + full_data_len = n_frames_div * size * (*n_values_per_frame); + if(is_particle_data == TNG_TRUE) + { + full_data_len *= (*n_particles); + } - temp = realloc(*values, data_size); + temp = realloc(*values, full_data_len); if(!temp) { fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - data_size, __FILE__, __LINE__); + full_data_len, __FILE__, __LINE__); free(*values); *values = 0; return(TNG_CRITICAL); @@ -16334,9 +14301,9 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_get *values = temp; - if(frame_set->n_mapping_blocks <= 0) + if(is_particle_data != TNG_TRUE || frame_set->n_mapping_blocks <= 0) { - memcpy(*values, data->values, data_size); + memcpy(*values, data->values, full_data_len); } else { @@ -16360,9 +14327,30 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_get return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get - (tng_trajectory_t tng_data, +tng_function_status DECLSPECDLLEXPORT tng_data_vector_get + (const tng_trajectory_t tng_data, + const int64_t block_id, + void **values, + int64_t *n_frames, + int64_t *stride_length, + int64_t *n_values_per_frame, + char *type) +{ + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(n_frames, "TNG library: n_frames must not be a NULL pointer."); + TNG_ASSERT(stride_length, "TNG library: stride_length must not be a NULL pointer."); + TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); + TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); + + return(tng_gen_data_vector_get(tng_data, block_id, TNG_FALSE, values, + n_frames, stride_length, 0, n_values_per_frame, + type)); +} + +static tng_function_status tng_gen_data_interval_get + (const tng_trajectory_t tng_data, const int64_t block_id, + const tng_bool is_particle_data, const int64_t start_frame_nr, const int64_t end_frame_nr, const char hash_mode, @@ -16375,18 +14363,12 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get int64_t first_frame, block_index; int size; size_t len; - tng_particle_data_t data; + tng_data_t data; tng_trajectory_frame_set_t frame_set; tng_gen_block_t block; char block_type_flag; tng_function_status stat; - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(start_frame_nr <= end_frame_nr, "TNG library: start_frame_nr must not be higher than tne end_frame_nr."); - TNG_ASSERT(n_particles, "TNG library: n_particles must not be a NULL pointer."); - TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); - TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); - block_index = -1; frame_set = &tng_data->current_trajectory_frame_set; @@ -16399,8 +14381,12 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get } /* Do not re-read the frame set. */ - if(first_frame != frame_set->first_frame || - frame_set->n_particle_data_blocks <= 0) + if((is_particle_data == TNG_TRUE && + (first_frame != frame_set->first_frame || + frame_set->n_particle_data_blocks <= 0)) || + (is_particle_data == TNG_FALSE && + (first_frame != frame_set->first_frame || + frame_set->n_data_blocks <= 0))) { tng_block_init(&block); file_pos = ftello(tng_data->input_file); @@ -16433,14 +14419,29 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get /* See if there is already a data block of this ID. * Start checking the last read frame set */ - for(i = frame_set->n_particle_data_blocks; i-- ;) + if(is_particle_data == TNG_TRUE) { - data = &frame_set->tr_particle_data[i]; - if(data->block_id == block_id) + for(i = frame_set->n_particle_data_blocks; i-- ;) { - block_index = i; - block_type_flag = TNG_TRAJECTORY_BLOCK; - break; + data = &frame_set->tr_particle_data[i]; + if(data->block_id == block_id) + { + block_index = i; + block_type_flag = TNG_TRAJECTORY_BLOCK; + break; + } + } + } + else + { + for(i = 0; i < frame_set->n_data_blocks; i++) + { + data = &frame_set->tr_data[i]; + if(data->block_id == block_id) + { + block_index = i; + break; + } } } @@ -16451,14 +14452,17 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get return(TNG_FAILURE); } - if(block_type_flag == TNG_TRAJECTORY_BLOCK && - tng_data->var_num_atoms_flag) - { - *n_particles = frame_set->n_particles; - } - else + if(is_particle_data == TNG_TRUE) { - *n_particles = tng_data->n_particles; + if(block_type_flag == TNG_TRAJECTORY_BLOCK && + tng_data->var_num_atoms_flag) + { + *n_particles = frame_set->n_particles; + } + else + { + *n_particles = tng_data->n_particles; + } } n_frames = end_frame_nr - start_frame_nr + 1; @@ -16467,16 +14471,36 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get if(*values == 0) { - if(tng_particle_data_values_alloc(tng_data, values, n_frames, - *n_particles, *n_values_per_frame, - *type) - != TNG_SUCCESS) + if(is_particle_data == TNG_TRUE) { - return(TNG_CRITICAL); + if(tng_particle_data_values_alloc(tng_data, values, n_frames, + *n_particles, *n_values_per_frame, + *type) != TNG_SUCCESS) + { + return(TNG_CRITICAL); + } + } + else + { + if(tng_data_values_alloc(tng_data, *values, n_frames, + *n_values_per_frame, + *type) != TNG_SUCCESS) + { + return(TNG_CRITICAL); + } } } current_frame_pos = start_frame_nr - frame_set->first_frame; + + if(is_particle_data == TNG_TRUE) + { + i_step = (*n_particles) * (*n_values_per_frame); + } + else + { + i_step = (*n_values_per_frame); + } /* It's not very elegant to reuse so much of the code in the different case * statements, but it's unnecessarily slow to have the switch-case block * inside the for loops. */ @@ -16494,14 +14518,26 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get } current_frame_pos = 0; } - for(j = 0; j < *n_particles; j++) + if(is_particle_data == TNG_TRUE) { - tng_particle_mapping_get_real_particle(frame_set, j, &mapping); - for(k = 0; k < *n_values_per_frame; k++) + for(j = 0; j < *n_particles; j++) + { + tng_particle_mapping_get_real_particle(frame_set, j, &mapping); + for(k = 0; k < *n_values_per_frame; k++) + { + len = strlen(data->strings[current_frame_pos][j][k]) + 1; + (*values)[i][mapping][k].c = malloc(len); + strncpy((*values)[i][mapping][k].c, data->strings[current_frame_pos][j][k], len); + } + } + } + else + { + for(j = 0; j < *n_values_per_frame; j++) { - len = strlen(data->strings[current_frame_pos][j][k]) + 1; - (*values)[i][mapping][k].c = malloc(len); - strncpy((*values)[i][mapping][k].c, data->strings[current_frame_pos][j][k], len); + len = strlen(data->strings[0][current_frame_pos][j]) + 1; + (*values)[0][i][j].c = malloc(len); + strncpy((*values)[0][i][j].c, data->strings[0][current_frame_pos][j], len); } } current_frame_pos++; @@ -16509,7 +14545,6 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get break; case TNG_INT_DATA: size = sizeof(int); - i_step = (*n_particles) * (*n_values_per_frame); for(i=0; in_frames) @@ -16521,24 +14556,35 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get } current_frame_pos = 0; } - for(j = 0; j < *n_particles; j++) + if(is_particle_data == TNG_TRUE) { - tng_particle_mapping_get_real_particle(frame_set, j, &mapping); - for(k = 0; k < *n_values_per_frame; k++) + for(j = 0; j < *n_particles; j++) { - (*values)[i][mapping][k].i = *(int *) - ((char *)data->values + size * - (current_frame_pos * - i_step + j * - (*n_values_per_frame) + k)); + tng_particle_mapping_get_real_particle(frame_set, j, &mapping); + for(k = 0; k < *n_values_per_frame; k++) + { + (*values)[i][mapping][k].i = *(int *) + ((char *)data->values + size * + (current_frame_pos * + i_step + j * + (*n_values_per_frame) + k)); + } + } + current_frame_pos++; + } + else + { + for(j = 0; j < *n_values_per_frame; j++) + { + (*values)[0][i][j].i = *(int *)((char *)data->values + size * + (current_frame_pos * + i_step + j)); } } - current_frame_pos++; } break; case TNG_FLOAT_DATA: size = sizeof(float); - i_step = (*n_particles) * (*n_values_per_frame); for(i=0; in_frames) @@ -16550,16 +14596,28 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get } current_frame_pos = 0; } - for(j=0; j<*n_particles; j++) + if(is_particle_data == TNG_TRUE) { - tng_particle_mapping_get_real_particle(frame_set, j, &mapping); - for(k=0; k<*n_values_per_frame; k++) + for(j=0; j<*n_particles; j++) + { + tng_particle_mapping_get_real_particle(frame_set, j, &mapping); + for(k=0; k<*n_values_per_frame; k++) + { + (*values)[i][mapping][k].f = *(float *) + ((char *)data->values + size * + (current_frame_pos * + i_step + j * + (*n_values_per_frame) + k)); + } + } + } + else + { + for(j = 0; j < *n_values_per_frame; j++) { - (*values)[i][mapping][k].f = *(float *) - ((char *)data->values + size * - (current_frame_pos * - i_step + j * - (*n_values_per_frame) + k)); + (*values)[0][i][j].f = *(float *)((char *)data->values + size * + (current_frame_pos * + i_step + j)); } } current_frame_pos++; @@ -16568,7 +14626,6 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get case TNG_DOUBLE_DATA: default: size = sizeof(double); - i_step = (*n_particles) * (*n_values_per_frame); for(i=0; in_frames) @@ -16580,16 +14637,28 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get } current_frame_pos = 0; } - for(j=0; j<*n_particles; j++) + if(is_particle_data == TNG_TRUE) { - tng_particle_mapping_get_real_particle(frame_set, j, &mapping); - for(k=0; k<*n_values_per_frame; k++) + for(j=0; j<*n_particles; j++) { - (*values)[i][mapping][k].d = *(double *) - ((char *)data->values + size * - (current_frame_pos * - i_step + j * - (*n_values_per_frame) + k)); + tng_particle_mapping_get_real_particle(frame_set, j, &mapping); + for(k=0; k<*n_values_per_frame; k++) + { + (*values)[i][mapping][k].d = *(double *) + ((char *)data->values + size * + (current_frame_pos * + i_step + j * + (*n_values_per_frame) + k)); + } + } + } + else + { + for(j = 0; j < *n_values_per_frame; j++) + { + (*values)[0][i][j].d = *(double *)((char *)data->values + size * + (current_frame_pos * + i_step + j)); } } current_frame_pos++; @@ -16601,9 +14670,30 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get return(TNG_SUCCESS); } -tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_interval_get - (tng_trajectory_t tng_data, +tng_function_status DECLSPECDLLEXPORT tng_data_interval_get + (const tng_trajectory_t tng_data, + const int64_t block_id, + const int64_t start_frame_nr, + const int64_t end_frame_nr, + const char hash_mode, + union data_values ***values, + int64_t *n_values_per_frame, + char *type) +{ + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(start_frame_nr <= end_frame_nr, "TNG library: start_frame_nr must not be higher than tne end_frame_nr."); + TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); + TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); + + return(tng_gen_data_interval_get(tng_data, block_id, TNG_FALSE, start_frame_nr, + end_frame_nr, hash_mode, &values, 0, + n_values_per_frame, type)); +} + +static tng_function_status tng_gen_data_vector_interval_get + (const tng_trajectory_t tng_data, const int64_t block_id, + const tng_bool is_particle_data, const int64_t start_frame_nr, const int64_t end_frame_nr, const char hash_mode, @@ -16614,21 +14704,14 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_interval_get char *type) { int64_t n_frames, tot_n_frames, n_frames_div, n_frames_div_2, first_frame; - int64_t file_pos, current_frame_pos, last_frame_pos, data_size, frame_size; + int64_t file_pos, current_frame_pos, last_frame_pos, full_data_len, frame_size; int size; tng_trajectory_frame_set_t frame_set; - tng_particle_data_t p_data; + tng_data_t data; tng_gen_block_t block; void *current_values = 0, *temp; tng_function_status stat; - TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(start_frame_nr <= end_frame_nr, "TNG library: start_frame_nr must not be higher than tne end_frame_nr."); - TNG_ASSERT(n_particles, "TNG library: n_particles must not be a NULL pointer."); - TNG_ASSERT(stride_length, "TNG library: stride_length must not be a NULL pointer."); - TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); - TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); - frame_set = &tng_data->current_trajectory_frame_set; first_frame = frame_set->first_frame; @@ -16640,7 +14723,15 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_interval_get /* Do not re-read the frame set and only need the requested block + particle mapping blocks. */ /* TODO: Test that blocks are read correctly now that now all of them are read at the same time. */ - stat = tng_particle_data_find(tng_data, block_id, &p_data); + if(is_particle_data == TNG_TRUE) + { + stat = tng_particle_data_find(tng_data, block_id, &data); + } + else + { + stat = tng_data_find(tng_data, block_id, &data); + } + if(first_frame != frame_set->first_frame || stat != TNG_SUCCESS) { @@ -16648,8 +14739,8 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_interval_get if(stat != TNG_SUCCESS) { fseeko(tng_data->input_file, - tng_data->current_trajectory_frame_set_input_file_pos, - SEEK_SET); + tng_data->current_trajectory_frame_set_input_file_pos, + SEEK_SET); stat = tng_block_header_read(tng_data, block); if(stat != TNG_SUCCESS) { @@ -16699,17 +14790,24 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_interval_get return(stat); } } - stat = tng_particle_data_find(tng_data, block_id, &p_data); + if(is_particle_data == TNG_TRUE) + { + stat = tng_particle_data_find(tng_data, block_id, &data); + } + else + { + stat = tng_data_find(tng_data, block_id, &data); + } if(stat != TNG_SUCCESS) { return(stat); } - stat = tng_particle_data_vector_get(tng_data, block_id, ¤t_values, - &n_frames, stride_length, n_particles, - n_values_per_frame, type); + stat = tng_gen_data_vector_get(tng_data, block_id, is_particle_data, + ¤t_values, &n_frames, stride_length, + n_particles, n_values_per_frame, type); - if(stat != TNG_SUCCESS || *n_particles == 0) + if(stat != TNG_SUCCESS || (is_particle_data && *n_particles == 0)) { if(current_values) { @@ -16746,14 +14844,17 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_interval_get tot_n_frames / *stride_length + 1: tot_n_frames / *stride_length; - data_size = n_frames_div * size * (*n_particles) * - (*n_values_per_frame); + full_data_len = n_frames_div * size * (*n_values_per_frame); + if(is_particle_data) + { + full_data_len *= (*n_particles); + } - temp = realloc(*values, data_size); + temp = realloc(*values, full_data_len); if(!temp) { fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - data_size, __FILE__, __LINE__); + full_data_len, __FILE__, __LINE__); free(*values); *values = 0; return(TNG_CRITICAL); @@ -16763,14 +14864,25 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_interval_get if( n_frames == 1 && n_frames < frame_set->n_frames) { - memcpy(*values, current_values, size * (*n_particles) * - (*n_values_per_frame)); + if(is_particle_data) + { + memcpy(*values, current_values, size * (*n_particles) * + (*n_values_per_frame)); + } + else + { + memcpy(*values, current_values, size * (*n_values_per_frame)); + } } else { current_frame_pos = start_frame_nr - frame_set->first_frame; - frame_size = size * (*n_particles) * (*n_values_per_frame); + frame_size = size * (*n_values_per_frame); + if(is_particle_data) + { + frame_size *= (*n_particles); + } last_frame_pos = tng_min_i64(n_frames, end_frame_nr - start_frame_nr); @@ -16800,9 +14912,10 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_interval_get return(stat); } - stat = tng_particle_data_vector_get(tng_data, block_id, ¤t_values, - &n_frames, stride_length, n_particles, - n_values_per_frame, type); + stat = tng_gen_data_vector_get(tng_data, block_id, is_particle_data, + ¤t_values, &n_frames, + stride_length, n_particles, + n_values_per_frame, type); if(stat != TNG_SUCCESS) { @@ -16837,9 +14950,121 @@ tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_interval_get free(current_values); } - p_data->last_retrieved_frame = end_frame_nr; + data->last_retrieved_frame = end_frame_nr; + + return(TNG_SUCCESS); +} + + +tng_function_status DECLSPECDLLEXPORT tng_data_vector_interval_get + (const tng_trajectory_t tng_data, + const int64_t block_id, + const int64_t start_frame_nr, + const int64_t end_frame_nr, + const char hash_mode, + void **values, + int64_t *stride_length, + int64_t *n_values_per_frame, + char *type) +{ + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(start_frame_nr <= end_frame_nr, "TNG library: start_frame_nr must not be higher than the end_frame_nr."); + TNG_ASSERT(stride_length, "TNG library: stride_length must not be a NULL pointer."); + TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); + TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); + + return(tng_gen_data_vector_interval_get(tng_data, block_id, TNG_FALSE, + start_frame_nr, end_frame_nr, + hash_mode, values, 0, stride_length, + n_values_per_frame, type)); +} + +tng_function_status DECLSPECDLLEXPORT tng_particle_data_get + (const tng_trajectory_t tng_data, + const int64_t block_id, + union data_values ****values, + int64_t *n_frames, + int64_t *n_particles, + int64_t *n_values_per_frame, + char *type) +{ + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(n_frames, "TNG library: n_frames must not be a NULL pointer."); + TNG_ASSERT(n_particles, "TNG library: n_particles must not be a NULL pointer."); + TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); + TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); + + return(tng_gen_data_get(tng_data, block_id, TNG_TRUE, values, n_frames, n_particles, + n_values_per_frame, type)); +} + +tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_get + (const tng_trajectory_t tng_data, + const int64_t block_id, + void **values, + int64_t *n_frames, + int64_t *stride_length, + int64_t *n_particles, + int64_t *n_values_per_frame, + char *type) +{ + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(n_particles, "TNG library: n_particles must not be a NULL pointer."); + TNG_ASSERT(stride_length, "TNG library: stride_length must not be a NULL pointer."); + TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); + TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); + + return(tng_gen_data_vector_get(tng_data, block_id, TNG_TRUE, values, + n_frames, stride_length, n_particles, + n_values_per_frame, type)); +} + +tng_function_status DECLSPECDLLEXPORT tng_particle_data_interval_get + (const tng_trajectory_t tng_data, + const int64_t block_id, + const int64_t start_frame_nr, + const int64_t end_frame_nr, + const char hash_mode, + union data_values ****values, + int64_t *n_particles, + int64_t *n_values_per_frame, + char *type) +{ + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(start_frame_nr <= end_frame_nr, "TNG library: start_frame_nr must not be higher than tne end_frame_nr."); + TNG_ASSERT(n_particles, "TNG library: n_particles must not be a NULL pointer."); + TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); + TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); + + return(tng_gen_data_interval_get(tng_data, block_id, TNG_TRUE, start_frame_nr, + end_frame_nr, hash_mode, values, n_particles, + n_values_per_frame, type)); +} + +tng_function_status DECLSPECDLLEXPORT tng_particle_data_vector_interval_get + (const tng_trajectory_t tng_data, + const int64_t block_id, + const int64_t start_frame_nr, + const int64_t end_frame_nr, + const char hash_mode, + void **values, + int64_t *n_particles, + int64_t *stride_length, + int64_t *n_values_per_frame, + char *type) +{ + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + TNG_ASSERT(start_frame_nr <= end_frame_nr, "TNG library: start_frame_nr must not be higher than tne end_frame_nr."); + TNG_ASSERT(n_particles, "TNG library: n_particles must not be a NULL pointer."); + TNG_ASSERT(stride_length, "TNG library: stride_length must not be a NULL pointer."); + TNG_ASSERT(n_values_per_frame, "TNG library: n_values_per_frame must not be a NULL pointer."); + TNG_ASSERT(type, "TNG library: type must not be a NULL pointer."); - return(TNG_SUCCESS); + return(tng_gen_data_vector_interval_get(tng_data, block_id, TNG_TRUE, + start_frame_nr, end_frame_nr, + hash_mode, values, n_particles, + stride_length, n_values_per_frame, + type)); } tng_function_status DECLSPECDLLEXPORT tng_data_get_stride_length @@ -16849,8 +15074,7 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get_stride_length int64_t *stride_length) { tng_function_status stat; - tng_non_particle_data_t np_data; - tng_particle_data_t p_data; + tng_data_t data; int64_t orig_file_pos, file_pos; int is_particle_data; @@ -16868,10 +15092,10 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get_stride_length } } orig_file_pos = tng_data->current_trajectory_frame_set_input_file_pos; - stat = tng_data_find(tng_data, block_id, &np_data); + stat = tng_data_find(tng_data, block_id, &data); if(stat != TNG_SUCCESS) { - stat = tng_particle_data_find(tng_data, block_id, &p_data); + stat = tng_particle_data_find(tng_data, block_id, &data); if(stat != TNG_SUCCESS) { stat = tng_frame_set_read_current_only_data_from_block_id(tng_data, TNG_USE_HASH, block_id); @@ -16891,10 +15115,10 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get_stride_length return(stat); } - stat = tng_data_find(tng_data, block_id, &np_data); + stat = tng_data_find(tng_data, block_id, &data); if(stat != TNG_SUCCESS) { - stat = tng_particle_data_find(tng_data, block_id, &p_data); + stat = tng_particle_data_find(tng_data, block_id, &data); if(stat != TNG_SUCCESS) { tng_reread_frame_set_at_file_pos(tng_data, orig_file_pos); @@ -16922,11 +15146,11 @@ tng_function_status DECLSPECDLLEXPORT tng_data_get_stride_length } if(is_particle_data) { - *stride_length = p_data->stride_length; + *stride_length = data->stride_length; } else { - *stride_length = np_data->stride_length; + *stride_length = data->stride_length; } tng_reread_frame_set_at_file_pos(tng_data, orig_file_pos); @@ -16992,7 +15216,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_open if(mode == 'w') { - tng_output_file_set(*tng_data_p, filename); + stat = tng_output_file_set(*tng_data_p, filename); } else if(mode == 'a') { @@ -17002,8 +15226,8 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_open } (*tng_data_p)->output_file = (*tng_data_p)->input_file; fseeko((*tng_data_p)->input_file, - (*tng_data_p)->last_trajectory_frame_set_input_file_pos, - SEEK_SET); + (*tng_data_p)->last_trajectory_frame_set_input_file_pos, + SEEK_SET); stat = tng_frame_set_read(*tng_data_p, TNG_USE_HASH); if(stat != TNG_SUCCESS) @@ -17034,7 +15258,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_open fseeko((*tng_data_p)->output_file, 0, SEEK_END); } - return(TNG_SUCCESS); + return(stat); } tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_close @@ -17066,7 +15290,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_close } tng_function_status DECLSPECDLLEXPORT tng_util_time_of_frame_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, double *time) { @@ -17100,7 +15324,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_time_of_frame_get /* tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_molecules_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, int64_t *n_mols, int64_t **molecule_cnt_list, tng_molecule_t *mols) @@ -17129,7 +15353,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_molecules_get */ /* tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_molecule_add - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const char *name, const int64_t cnt, tng_molecule_t *mol) @@ -17150,7 +15374,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_molecule_add } */ tng_function_status DECLSPECDLLEXPORT tng_util_molecule_particles_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const tng_molecule_t mol, int64_t *n_particles, char ***names, @@ -17196,8 +15420,8 @@ tng_function_status DECLSPECDLLEXPORT tng_util_molecule_particles_get } tng_function_status DECLSPECDLLEXPORT tng_util_molecule_particles_set - (tng_trajectory_t tng_data, - tng_molecule_t mol, + (const tng_trajectory_t tng_data, + const tng_molecule_t mol, const int64_t n_particles, const char **names, const char **types, @@ -17252,7 +15476,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_molecule_particles_set } tng_function_status DECLSPECDLLEXPORT tng_util_pos_read - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, float **positions, int64_t *stride_length) { int64_t n_frames, n_particles, n_values_per_frame; @@ -17281,7 +15505,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_read } tng_function_status DECLSPECDLLEXPORT tng_util_vel_read - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, float **velocities, int64_t *stride_length) { int64_t n_frames, n_particles, n_values_per_frame; @@ -17310,7 +15534,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_read } tng_function_status DECLSPECDLLEXPORT tng_util_force_read - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, float **forces, int64_t *stride_length) { int64_t n_frames, n_particles, n_values_per_frame; @@ -17339,7 +15563,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_read } tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_read - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, float **box_shape, int64_t *stride_length) { @@ -17368,7 +15592,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_read } tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t block_id, void **values, char *data_type, @@ -17376,11 +15600,12 @@ tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read double *retrieved_time) { tng_trajectory_frame_set_t frame_set; - tng_particle_data_t data = 0; + tng_data_t data = 0; tng_function_status stat; int size; - int64_t i, data_size, n_particles, file_pos; + int64_t i, full_data_len, n_particles; void *temp; + int64_t file_pos; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); TNG_ASSERT(values, "TNG library: The pointer to the values array must not be a NULL pointer"); @@ -17413,8 +15638,8 @@ tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read if(data->last_retrieved_frame < 0) { fseeko(tng_data->input_file, - tng_data->first_trajectory_frame_set_input_file_pos, - SEEK_SET); + 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) { @@ -17430,7 +15655,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read } else { - if(data->n_frames == 1) + if(data->n_frames == 1 && frame_set->n_frames == 1) { i = data->last_retrieved_frame + 1; } @@ -17508,16 +15733,16 @@ tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read size = sizeof(double); } - data_size = size * n_particles * data->n_values_per_frame; + full_data_len = size * n_particles * data->n_values_per_frame; -// fprintf(stderr, "TNG library: TEMP: i = %"PRId64", data_size = %"PRId64", size = %d, n_particles = %"PRId64", n_values_per_frame = %"PRId64"\n", -// i, data_size, size, n_particles, data->n_values_per_frame); +// fprintf(stderr, "TNG library: TEMP: i = %"PRId64", full_data_len = %"PRId64", size = %d, n_particles = %"PRId64", n_values_per_frame = %"PRId64"\n", +// i, full_data_len, size, n_particles, data->n_values_per_frame); - temp = realloc(*values, data_size); + temp = realloc(*values, full_data_len); if(!temp) { fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - data_size, __FILE__, __LINE__); + full_data_len, __FILE__, __LINE__); free(*values); *values = 0; return(TNG_CRITICAL); @@ -17525,13 +15750,13 @@ tng_function_status DECLSPECDLLEXPORT tng_util_particle_data_next_frame_read *values = temp; - memcpy(*values, (char *)data->values + i * data_size, data_size); + memcpy(*values, (char *)data->values + i * full_data_len, full_data_len); return(TNG_SUCCESS); } tng_function_status DECLSPECDLLEXPORT tng_util_non_particle_data_next_frame_read - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t block_id, void **values, char *data_type, @@ -17539,11 +15764,12 @@ tng_function_status DECLSPECDLLEXPORT tng_util_non_particle_data_next_frame_read double *retrieved_time) { tng_trajectory_frame_set_t frame_set; - tng_non_particle_data_t data = 0; + tng_data_t data = 0; tng_function_status stat; int size; - int64_t i, data_size, file_pos; + int64_t i, full_data_len; void *temp; + int64_t file_pos; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); TNG_ASSERT(values, "TNG library: The pointer to the values array must not be a NULL pointer"); @@ -17576,8 +15802,8 @@ tng_function_status DECLSPECDLLEXPORT tng_util_non_particle_data_next_frame_read if(data->last_retrieved_frame < 0) { fseeko(tng_data->input_file, - tng_data->first_trajectory_frame_set_input_file_pos, - SEEK_SET); + 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) { @@ -17593,7 +15819,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_non_particle_data_next_frame_read } else { - if(data->n_frames == 1) + if(data->n_frames == 1 && frame_set->n_frames == 1) { i = data->last_retrieved_frame + 1; } @@ -17669,13 +15895,13 @@ tng_function_status DECLSPECDLLEXPORT tng_util_non_particle_data_next_frame_read size = sizeof(double); } - data_size = size * data->n_values_per_frame; + full_data_len = size * data->n_values_per_frame; - temp = realloc(*values, data_size); + temp = realloc(*values, full_data_len); if(!temp) { fprintf(stderr, "TNG library: Cannot allocate memory (%"PRId64" bytes). %s: %d\n", - data_size, __FILE__, __LINE__); + full_data_len, __FILE__, __LINE__); free(*values); *values = 0; return(TNG_CRITICAL); @@ -17683,13 +15909,13 @@ tng_function_status DECLSPECDLLEXPORT tng_util_non_particle_data_next_frame_read *values = temp; - memcpy(*values, (char *)data->values + i * data_size, data_size); + memcpy(*values, (char *)data->values + i * full_data_len, full_data_len); return(TNG_SUCCESS); } tng_function_status DECLSPECDLLEXPORT tng_util_pos_read_range - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t first_frame, const int64_t last_frame, float **positions, @@ -17713,11 +15939,16 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_read_range &n_values_per_frame, &type); + if(stat == TNG_SUCCESS && type != TNG_FLOAT_DATA) + { + return(TNG_FAILURE); + } + return(stat); } tng_function_status DECLSPECDLLEXPORT tng_util_vel_read_range - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t first_frame, const int64_t last_frame, float **velocities, @@ -17741,11 +15972,16 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_read_range &n_values_per_frame, &type); + if(stat == TNG_SUCCESS && type != TNG_FLOAT_DATA) + { + return(TNG_FAILURE); + } + return(stat); } tng_function_status DECLSPECDLLEXPORT tng_util_force_read_range - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t first_frame, const int64_t last_frame, float **forces, @@ -17769,11 +16005,16 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_read_range &n_values_per_frame, &type); + if(stat == TNG_SUCCESS && type != TNG_FLOAT_DATA) + { + return(TNG_FAILURE); + } + return(stat); } tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_read_range - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t first_frame, const int64_t last_frame, float **box_shape, @@ -17796,11 +16037,16 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_read_range &n_values_per_frame, &type); + if(stat == TNG_SUCCESS && type != TNG_FLOAT_DATA) + { + return(TNG_FAILURE); + } + return(stat); } tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i, const int64_t n_values_per_frame, const int64_t block_id, @@ -17809,8 +16055,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_set const char compression) { tng_trajectory_frame_set_t frame_set; - tng_particle_data_t p_data; - tng_non_particle_data_t np_data; + tng_data_t data; int64_t n_particles, n_frames; tng_function_status stat; @@ -17851,7 +16096,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_set return(TNG_FAILURE); } - if(tng_particle_data_find(tng_data, block_id, &p_data) + if(tng_particle_data_find(tng_data, block_id, &data) != TNG_SUCCESS) { stat = tng_particle_data_block_add(tng_data, block_id, @@ -17867,9 +16112,9 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_set __FILE__, __LINE__); return(stat); } - p_data = &frame_set->tr_particle_data[frame_set-> + data = &frame_set->tr_particle_data[frame_set-> n_particle_data_blocks - 1]; - stat = tng_allocate_particle_data_mem(tng_data, p_data, n_frames, + stat = tng_allocate_particle_data_mem(tng_data, data, n_frames, i, n_particles, n_values_per_frame); if(stat != TNG_SUCCESS) @@ -17881,10 +16126,10 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_set } else { - if(p_data->stride_length != i) + if(data->stride_length != i) { - p_data->stride_length = i; - stat = tng_allocate_particle_data_mem(tng_data, p_data, n_frames, + data->stride_length = i; + stat = tng_allocate_particle_data_mem(tng_data, data, n_frames, i, n_particles, n_values_per_frame); if(stat != TNG_SUCCESS) @@ -17898,7 +16143,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_set } else { - if(tng_data_find(tng_data, block_id, &np_data) != TNG_SUCCESS) + if(tng_data_find(tng_data, block_id, &data) != TNG_SUCCESS) { stat = tng_data_block_add(tng_data, block_id, block_name, TNG_FLOAT_DATA, TNG_TRAJECTORY_BLOCK, @@ -17910,9 +16155,9 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_set __FILE__, __LINE__); return(stat); } - np_data = &frame_set->tr_data[frame_set-> + data = &frame_set->tr_data[frame_set-> n_data_blocks - 1]; - stat = tng_allocate_data_mem(tng_data, np_data, n_frames, + stat = tng_allocate_data_mem(tng_data, data, n_frames, i, n_values_per_frame); if(stat != TNG_SUCCESS) { @@ -17923,10 +16168,10 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_set } else { - if(np_data->stride_length != i) + if(data->stride_length != i) { - np_data->stride_length = i; - stat = tng_allocate_data_mem(tng_data, np_data, n_frames, + data->stride_length = i; + stat = tng_allocate_data_mem(tng_data, data, n_frames, i, n_values_per_frame); if(stat != TNG_SUCCESS) { @@ -17942,7 +16187,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_set } tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_double_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i, const int64_t n_values_per_frame, const int64_t block_id, @@ -17951,8 +16196,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_double_set const char compression) { tng_trajectory_frame_set_t frame_set; - tng_particle_data_t p_data; - tng_non_particle_data_t np_data; + tng_data_t data; int64_t n_particles, n_frames; tng_function_status stat; @@ -17994,7 +16238,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_double_set return(TNG_FAILURE); } - if(tng_particle_data_find(tng_data, block_id, &p_data) + if(tng_particle_data_find(tng_data, block_id, &data) != TNG_SUCCESS) { stat = tng_particle_data_block_add(tng_data, block_id, @@ -18010,9 +16254,9 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_double_set __FILE__, __LINE__); return(stat); } - p_data = &frame_set->tr_particle_data[frame_set-> + data = &frame_set->tr_particle_data[frame_set-> n_particle_data_blocks - 1]; - stat = tng_allocate_particle_data_mem(tng_data, p_data, n_frames, + stat = tng_allocate_particle_data_mem(tng_data, data, n_frames, i, n_particles, n_values_per_frame); if(stat != TNG_SUCCESS) @@ -18024,12 +16268,12 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_double_set } else { - p_data->stride_length = i; + data->stride_length = i; } } else { - if(tng_data_find(tng_data, block_id, &np_data) != TNG_SUCCESS) + if(tng_data_find(tng_data, block_id, &data) != TNG_SUCCESS) { stat = tng_data_block_add(tng_data, block_id, block_name, TNG_DOUBLE_DATA, TNG_TRAJECTORY_BLOCK, @@ -18041,9 +16285,9 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_double_set __FILE__, __LINE__); return(stat); } - np_data = &frame_set->tr_data[frame_set-> + data = &frame_set->tr_data[frame_set-> n_data_blocks - 1]; - stat = tng_allocate_data_mem(tng_data, np_data, n_frames, + stat = tng_allocate_data_mem(tng_data, data, n_frames, i, n_values_per_frame); if(stat != TNG_SUCCESS) { @@ -18054,7 +16298,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_double_set } else { - np_data->stride_length = i; + data->stride_length = i; } } @@ -18062,7 +16306,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_interval_double_set } tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_frequency_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i, const int64_t n_values_per_frame, const int64_t block_id, @@ -18078,7 +16322,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write_frequency_set compression)); } tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_interval_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); @@ -18092,7 +16336,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_interval_set } tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_interval_double_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); @@ -18106,7 +16350,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_interval_double_set } tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_frequency_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i) { fprintf(stderr, "TNG library: Using obsolete function tng_util_pos_write_frequency_set(). " @@ -18115,7 +16359,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_write_frequency_set } tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_interval_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); @@ -18129,7 +16373,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_interval_set } tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_interval_double_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); @@ -18143,7 +16387,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_interval_double_set } tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_frequency_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i) { fprintf(stderr, "TNG library: Using obsolete function tng_util_vel_write_frequency_set(). " @@ -18152,7 +16396,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_write_frequency_set } tng_function_status DECLSPECDLLEXPORT tng_util_force_write_interval_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); @@ -18166,7 +16410,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_write_interval_set } tng_function_status DECLSPECDLLEXPORT tng_util_force_write_interval_double_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); @@ -18180,7 +16424,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_write_interval_double_set } tng_function_status DECLSPECDLLEXPORT tng_util_force_write_frequency_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i) { fprintf(stderr, "TNG library: Using obsolete function tng_util_force_write_frequency_set(). " @@ -18189,7 +16433,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_write_frequency_set } tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_interval_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); @@ -18203,7 +16447,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_interval_set } tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_interval_double_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); @@ -18217,7 +16461,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_interval_double_s } tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_frequency_set - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t i) { fprintf(stderr, "TNG library: Using obsolete function tng_util_box_shape_write_frequency_set(). " @@ -18226,7 +16470,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write_frequency_set } tng_function_status DECLSPECDLLEXPORT tng_util_generic_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const float *values, const int64_t n_values_per_frame, @@ -18236,8 +16480,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write const char compression) { tng_trajectory_frame_set_t frame_set; - tng_particle_data_t p_data; - tng_non_particle_data_t np_data; + tng_data_t data; int64_t n_particles = 0, n_frames, stride_length = 100, frame_pos; int64_t last_frame; int is_first_frame_flag = 0; @@ -18245,7 +16488,6 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write tng_function_status stat; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(frame_nr >= 0, "TNG library: frame_nr must be >= 0."); TNG_ASSERT(values, "TNG library: values must not be a NULL pointer"); if(particle_dependency == TNG_PARTICLE_BLOCK_DATA) @@ -18316,7 +16558,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write if(particle_dependency == TNG_PARTICLE_BLOCK_DATA) { - if(tng_particle_data_find(tng_data, block_id, &p_data) + if(tng_particle_data_find(tng_data, block_id, &data) != TNG_SUCCESS) { stat = tng_particle_data_block_add(tng_data, block_id, @@ -18335,15 +16577,15 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write } if(block_type_flag == TNG_TRAJECTORY_BLOCK) { - p_data = &frame_set->tr_particle_data[frame_set-> + data = &frame_set->tr_particle_data[frame_set-> n_particle_data_blocks - 1]; } else { - p_data = &tng_data->non_tr_particle_data[tng_data-> - n_particle_data_blocks - 1]; + data = &tng_data->non_tr_particle_data[tng_data-> + n_particle_data_blocks - 1]; } - stat = tng_allocate_particle_data_mem(tng_data, p_data, n_frames, + stat = tng_allocate_particle_data_mem(tng_data, data, n_frames, stride_length, n_particles, n_values_per_frame); if(stat != TNG_SUCCESS) @@ -18353,14 +16595,27 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write return(stat); } } + /* FIXME: Here we must be able to handle modified n_particles as well. */ + else if(n_frames > data->n_frames) + { + stat = tng_allocate_particle_data_mem(tng_data, data, n_frames, + data->stride_length, n_particles, + n_values_per_frame); + if(stat != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Error allocating particle data memory. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + } if(block_type_flag == TNG_TRAJECTORY_BLOCK) { - stride_length = p_data->stride_length; + stride_length = data->stride_length; - if(is_first_frame_flag || p_data->first_frame_with_data < frame_set->first_frame) + if(is_first_frame_flag || data->first_frame_with_data < frame_set->first_frame) { - p_data->first_frame_with_data = frame_nr; + data->first_frame_with_data = frame_nr; frame_pos = 0; } else @@ -18368,19 +16623,19 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write frame_pos = (frame_nr - frame_set->first_frame) / stride_length; } - memcpy((char *)p_data->values + sizeof(float) * frame_pos * n_particles * + memcpy((char *)data->values + sizeof(float) * frame_pos * n_particles * n_values_per_frame, values, sizeof(float) * n_particles * n_values_per_frame); } else { - memcpy(p_data->values, values, sizeof(float) * n_particles * + memcpy(data->values, values, sizeof(float) * n_particles * n_values_per_frame); } } else { - if(tng_data_find(tng_data, block_id, &np_data) != TNG_SUCCESS) + if(tng_data_find(tng_data, block_id, &data) != TNG_SUCCESS) { stat = tng_data_block_add(tng_data, block_id, block_name, TNG_FLOAT_DATA, block_type_flag, @@ -18394,15 +16649,15 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write } if(block_type_flag == TNG_TRAJECTORY_BLOCK) { - np_data = &frame_set->tr_data[frame_set-> + data = &frame_set->tr_data[frame_set-> n_data_blocks - 1]; } else { - np_data = &tng_data->non_tr_data[tng_data-> + data = &tng_data->non_tr_data[tng_data-> n_data_blocks - 1]; } - stat = tng_allocate_data_mem(tng_data, np_data, n_frames, + stat = tng_allocate_data_mem(tng_data, data, n_frames, stride_length, n_values_per_frame); if(stat != TNG_SUCCESS) { @@ -18411,14 +16666,26 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write return(stat); } } + /* FIXME: Here we must be able to handle modified n_particles as well. */ + else if(n_frames > data->n_frames) + { + stat = tng_allocate_data_mem(tng_data, data, n_frames, + data->stride_length, n_values_per_frame); + if(stat != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Error allocating particle data memory. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + } if(block_type_flag == TNG_TRAJECTORY_BLOCK) { - stride_length = np_data->stride_length; + stride_length = data->stride_length; - if(is_first_frame_flag || np_data->first_frame_with_data < frame_set->first_frame) + if(is_first_frame_flag || data->first_frame_with_data < frame_set->first_frame) { - np_data->first_frame_with_data = frame_nr; + data->first_frame_with_data = frame_nr; frame_pos = 0; } else @@ -18426,13 +16693,13 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write frame_pos = (frame_nr - frame_set->first_frame) / stride_length; } - memcpy((char *)np_data->values + sizeof(float) * frame_pos * + memcpy((char *)data->values + sizeof(float) * frame_pos * n_values_per_frame, values, sizeof(float) * n_values_per_frame); } else { - memcpy(np_data->values, values, sizeof(float) * n_values_per_frame); + memcpy(data->values, values, sizeof(float) * n_values_per_frame); } } @@ -18440,7 +16707,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_write } tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double *values, const int64_t n_values_per_frame, @@ -18450,8 +16717,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write const char compression) { tng_trajectory_frame_set_t frame_set; - tng_particle_data_t p_data; - tng_non_particle_data_t np_data; + tng_data_t data; int64_t n_particles = 0, n_frames, stride_length = 100, frame_pos; int64_t last_frame; int is_first_frame_flag = 0; @@ -18459,7 +16725,6 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write tng_function_status stat; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(frame_nr >= 0, "TNG library: frame_nr must be >= 0."); TNG_ASSERT(values, "TNG library: values must not be a NULL pointer"); if(particle_dependency == TNG_PARTICLE_BLOCK_DATA) @@ -18484,11 +16749,9 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write { block_type_flag = TNG_TRAJECTORY_BLOCK; - n_frames = tng_data->frame_set_n_frames; - if(!frame_set || tng_data->n_trajectory_frame_sets <= 0) { - stat = tng_frame_set_new(tng_data, 0, n_frames); + stat = tng_frame_set_new(tng_data, 0, tng_data->frame_set_n_frames); if(stat != TNG_SUCCESS) { fprintf(stderr, "TNG library: Cannot create frame set. %s: %d\n", __FILE__, @@ -18496,10 +16759,6 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write return(stat); } } - else - { - n_frames = frame_set->n_frames; - } last_frame = frame_set->first_frame + frame_set->n_frames - 1; if(frame_nr > last_frame) @@ -18515,7 +16774,8 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write { last_frame = frame_nr - 1; } - stat = tng_frame_set_new(tng_data, last_frame + 1, n_frames); + stat = tng_frame_set_new(tng_data, last_frame + 1, + tng_data->frame_set_n_frames); if(stat != TNG_SUCCESS) { fprintf(stderr, "TNG library: Cannot create frame set. %s: %d\n", __FILE__, @@ -18529,11 +16789,14 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write } frame_set->n_unwritten_frames = frame_nr - frame_set->first_frame + 1; + + n_frames = frame_set->n_frames; } + if(particle_dependency == TNG_PARTICLE_BLOCK_DATA) { - if(tng_particle_data_find(tng_data, block_id, &p_data) + if(tng_particle_data_find(tng_data, block_id, &data) != TNG_SUCCESS) { stat = tng_particle_data_block_add(tng_data, block_id, @@ -18552,15 +16815,15 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write } if(block_type_flag == TNG_TRAJECTORY_BLOCK) { - p_data = &frame_set->tr_particle_data[frame_set-> + data = &frame_set->tr_particle_data[frame_set-> n_particle_data_blocks - 1]; } else { - p_data = &tng_data->non_tr_particle_data[tng_data-> + data = &tng_data->non_tr_particle_data[tng_data-> n_particle_data_blocks - 1]; } - stat = tng_allocate_particle_data_mem(tng_data, p_data, n_frames, + stat = tng_allocate_particle_data_mem(tng_data, data, n_frames, stride_length, n_particles, n_values_per_frame); if(stat != TNG_SUCCESS) @@ -18570,14 +16833,27 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write return(stat); } } + /* FIXME: Here we must be able to handle modified n_particles as well. */ + else if(n_frames > data->n_frames) + { + stat = tng_allocate_particle_data_mem(tng_data, data, n_frames, + data->stride_length, n_particles, + n_values_per_frame); + if(stat != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Error allocating particle data memory. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + } if(block_type_flag == TNG_TRAJECTORY_BLOCK) { - stride_length = p_data->stride_length; + stride_length = data->stride_length; - if(is_first_frame_flag) + if(is_first_frame_flag || data->first_frame_with_data < frame_set->first_frame) { - p_data->first_frame_with_data = frame_nr; + data->first_frame_with_data = frame_nr; frame_pos = 0; } else @@ -18585,19 +16861,19 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write frame_pos = (frame_nr - frame_set->first_frame) / stride_length; } - memcpy((char *)p_data->values + sizeof(double) * frame_pos * n_particles * + memcpy((char *)data->values + sizeof(double) * frame_pos * n_particles * n_values_per_frame, values, sizeof(double) * n_particles * n_values_per_frame); } else { - memcpy(p_data->values, values, sizeof(double) * n_particles * + memcpy(data->values, values, sizeof(double) * n_particles * n_values_per_frame); } } else { - if(tng_data_find(tng_data, block_id, &np_data) != TNG_SUCCESS) + if(tng_data_find(tng_data, block_id, &data) != TNG_SUCCESS) { stat = tng_data_block_add(tng_data, block_id, block_name, TNG_DOUBLE_DATA, block_type_flag, @@ -18611,15 +16887,15 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write } if(block_type_flag == TNG_TRAJECTORY_BLOCK) { - np_data = &frame_set->tr_data[frame_set-> + data = &frame_set->tr_data[frame_set-> n_data_blocks - 1]; } else { - np_data = &tng_data->non_tr_data[tng_data-> + data = &tng_data->non_tr_data[tng_data-> n_data_blocks - 1]; } - stat = tng_allocate_data_mem(tng_data, np_data, n_frames, + stat = tng_allocate_data_mem(tng_data, data, n_frames, stride_length, n_values_per_frame); if(stat != TNG_SUCCESS) { @@ -18628,14 +16904,26 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write return(stat); } } + /* FIXME: Here we must be able to handle modified n_particles as well. */ + else if(n_frames > data->n_frames) + { + stat = tng_allocate_data_mem(tng_data, data, n_frames, + data->stride_length, n_values_per_frame); + if(stat != TNG_SUCCESS) + { + fprintf(stderr, "TNG library: Error allocating particle data memory. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + } if(block_type_flag == TNG_TRAJECTORY_BLOCK) { - stride_length = np_data->stride_length; + stride_length = data->stride_length; - if(is_first_frame_flag) + if(is_first_frame_flag || data->first_frame_with_data < frame_set->first_frame) { - np_data->first_frame_with_data = frame_nr; + data->first_frame_with_data = frame_nr; frame_pos = 0; } else @@ -18643,13 +16931,13 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write frame_pos = (frame_nr - frame_set->first_frame) / stride_length; } - memcpy((char *)np_data->values + sizeof(double) * frame_pos * + memcpy((char *)data->values + sizeof(double) * frame_pos * n_values_per_frame, values, sizeof(double) * n_values_per_frame); } else { - memcpy(np_data->values, values, sizeof(double) * n_values_per_frame); + memcpy(data->values, values, sizeof(double) * n_values_per_frame); } } @@ -18657,12 +16945,11 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_double_write } tng_function_status DECLSPECDLLEXPORT tng_util_pos_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const float *positions) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(frame_nr >= 0, "TNG library: frame_nr must be >= 0."); TNG_ASSERT(positions, "TNG library: positions must not be a NULL pointer"); return(tng_util_generic_write(tng_data, frame_nr, positions, 3, @@ -18672,12 +16959,11 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_write } tng_function_status DECLSPECDLLEXPORT tng_util_pos_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double *positions) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(frame_nr >= 0, "TNG library: frame_nr must be >= 0."); TNG_ASSERT(positions, "TNG library: positions must not be a NULL pointer"); return(tng_util_generic_double_write(tng_data, frame_nr, positions, 3, @@ -18687,12 +16973,11 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_double_write } tng_function_status DECLSPECDLLEXPORT tng_util_vel_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const float *velocities) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(frame_nr >= 0, "TNG library: frame_nr must be >= 0."); TNG_ASSERT(velocities, "TNG library: velocities must not be a NULL pointer"); return(tng_util_generic_write(tng_data, frame_nr, velocities, 3, @@ -18702,12 +16987,11 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_write } tng_function_status DECLSPECDLLEXPORT tng_util_vel_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double *velocities) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(frame_nr >= 0, "TNG library: frame_nr must be >= 0."); TNG_ASSERT(velocities, "TNG library: velocities must not be a NULL pointer"); return(tng_util_generic_double_write(tng_data, frame_nr, velocities, 3, @@ -18717,12 +17001,11 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_double_write } tng_function_status DECLSPECDLLEXPORT tng_util_force_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const float *forces) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(frame_nr >= 0, "TNG library: frame_nr must be >= 0."); TNG_ASSERT(forces, "TNG library: forces must not be a NULL pointer"); return(tng_util_generic_write(tng_data, frame_nr, forces, 3, @@ -18732,12 +17015,11 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_write } tng_function_status DECLSPECDLLEXPORT tng_util_force_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double *forces) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(frame_nr >= 0, "TNG library: frame_nr must be >= 0."); TNG_ASSERT(forces, "TNG library: forces must not be a NULL pointer"); return(tng_util_generic_double_write(tng_data, frame_nr, forces, 3, @@ -18747,12 +17029,11 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_double_write } tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const float *box_shape) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(frame_nr >= 0, "TNG library: frame_nr must be >= 0."); TNG_ASSERT(box_shape, "TNG library: box_shape must not be a NULL pointer"); return(tng_util_generic_write(tng_data, frame_nr, box_shape, 9, @@ -18762,12 +17043,11 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_write } tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double *box_shape) { TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); - TNG_ASSERT(frame_nr >= 0, "TNG library: frame_nr must be >= 0."); TNG_ASSERT(box_shape, "TNG library: box_shape must not be a NULL pointer"); return(tng_util_generic_double_write(tng_data, frame_nr, box_shape, 9, @@ -18777,7 +17057,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_double_write } tng_function_status DECLSPECDLLEXPORT tng_util_generic_with_time_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const float *values, @@ -18827,7 +17107,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_with_time_write } tng_function_status DECLSPECDLLEXPORT tng_util_generic_with_time_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const double *values, @@ -18877,7 +17157,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_generic_with_time_double_write } tng_function_status DECLSPECDLLEXPORT tng_util_pos_with_time_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const float *positions) @@ -18894,7 +17174,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_with_time_write } tng_function_status DECLSPECDLLEXPORT tng_util_pos_with_time_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const double *positions) @@ -18913,7 +17193,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_pos_with_time_double_write } tng_function_status DECLSPECDLLEXPORT tng_util_vel_with_time_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const float *velocities) @@ -18932,7 +17212,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_with_time_write } tng_function_status DECLSPECDLLEXPORT tng_util_vel_with_time_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const double *velocities) @@ -18951,7 +17231,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_vel_with_time_double_write } tng_function_status DECLSPECDLLEXPORT tng_util_force_with_time_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const float *forces) @@ -18968,7 +17248,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_with_time_write } tng_function_status DECLSPECDLLEXPORT tng_util_force_with_time_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const double *forces) @@ -18986,7 +17266,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_force_with_time_double_write } tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_with_time_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const float *box_shape) @@ -19003,7 +17283,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_with_time_write } tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_with_time_double_write - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t frame_nr, const double time, const double *box_shape) @@ -19022,14 +17302,13 @@ tng_function_status DECLSPECDLLEXPORT tng_util_box_shape_with_time_double_write } tng_function_status DECLSPECDLLEXPORT tng_util_frame_current_compression_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t block_id, int64_t *codec_id, double *factor) { tng_trajectory_frame_set_t frame_set; - tng_particle_data_t p_data = 0; - tng_non_particle_data_t np_data = 0; + tng_data_t data = 0; tng_function_status stat; int64_t i; int block_type = -1; @@ -19040,14 +17319,14 @@ tng_function_status DECLSPECDLLEXPORT tng_util_frame_current_compression_get frame_set = &tng_data->current_trajectory_frame_set; - stat = tng_particle_data_find(tng_data, block_id, &p_data); + stat = tng_particle_data_find(tng_data, block_id, &data); if(stat == TNG_SUCCESS) { block_type = TNG_PARTICLE_BLOCK_DATA; } else { - stat = tng_data_find(tng_data, block_id, &np_data); + stat = tng_data_find(tng_data, block_id, &data); if(stat == TNG_SUCCESS) { block_type = TNG_NON_PARTICLE_BLOCK_DATA; @@ -19059,14 +17338,14 @@ tng_function_status DECLSPECDLLEXPORT tng_util_frame_current_compression_get { return(stat); } - stat = tng_particle_data_find(tng_data, block_id, &p_data); + stat = tng_particle_data_find(tng_data, block_id, &data); if(stat == TNG_SUCCESS) { block_type = TNG_PARTICLE_BLOCK_DATA; } else { - stat = tng_data_find(tng_data, block_id, &np_data); + stat = tng_data_find(tng_data, block_id, &data); if(stat == TNG_SUCCESS) { block_type = TNG_NON_PARTICLE_BLOCK_DATA; @@ -19080,24 +17359,24 @@ tng_function_status DECLSPECDLLEXPORT tng_util_frame_current_compression_get } if(block_type == TNG_PARTICLE_BLOCK_DATA) { - if(p_data->last_retrieved_frame < 0) + if(data->last_retrieved_frame < 0) { - i = p_data->first_frame_with_data; + i = data->first_frame_with_data; } else { - i = p_data->last_retrieved_frame; + i = data->last_retrieved_frame; } } else if(block_type == TNG_NON_PARTICLE_BLOCK_DATA) { - if(np_data->last_retrieved_frame < 0) + if(data->last_retrieved_frame < 0) { - i = np_data->first_frame_with_data; + i = data->first_frame_with_data; } else { - i = np_data->last_retrieved_frame; + i = data->last_retrieved_frame; } } else @@ -19121,19 +17400,19 @@ tng_function_status DECLSPECDLLEXPORT tng_util_frame_current_compression_get } if(block_type == TNG_PARTICLE_BLOCK_DATA) { - *codec_id = p_data->codec_id; - *factor = p_data->compression_multiplier; + *codec_id = data->codec_id; + *factor = data->compression_multiplier; } else if(block_type == TNG_NON_PARTICLE_BLOCK_DATA) { - *codec_id = np_data->codec_id; - *factor = np_data->compression_multiplier; + *codec_id = data->codec_id; + *factor = data->compression_multiplier; } return(TNG_SUCCESS); } tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_data_blocks_find - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, int64_t current_frame, const int64_t n_requested_data_block_ids, const int64_t *requested_data_block_ids, @@ -19143,13 +17422,13 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_dat { tng_trajectory_frame_set_t frame_set; tng_function_status stat; - tng_particle_data_t p_data; - tng_non_particle_data_t np_data; + tng_data_t data; tng_gen_block_t block; int64_t i, j, block_id, *temp; int64_t data_frame, frame_diff, min_diff; - int64_t size, frame_set_file_pos, file_pos; + int64_t size, frame_set_file_pos; int found, read_all = 0; + int64_t file_pos; TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); TNG_ASSERT(next_frame, "TNG library: The pointer to the next frame must not be NULL."); @@ -19238,8 +17517,8 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_dat for(i = 0; i < frame_set->n_particle_data_blocks; i++) { - p_data = &frame_set->tr_particle_data[i]; - block_id = p_data->block_id; + data = &frame_set->tr_particle_data[i]; + block_id = data->block_id; if(n_requested_data_block_ids > 0) { @@ -19258,8 +17537,8 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_dat } } - if(!read_all && (p_data->last_retrieved_frame < frame_set->first_frame || - p_data->last_retrieved_frame >= + if(!read_all && (data->last_retrieved_frame < frame_set->first_frame || + data->last_retrieved_frame >= frame_set->first_frame + frame_set->n_frames)) { stat = tng_frame_set_read_current_only_data_from_block_id(tng_data, @@ -19276,13 +17555,13 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_dat } } if(frame_set->first_frame != current_frame && - p_data->last_retrieved_frame >= 0) + data->last_retrieved_frame >= 0) { - data_frame = p_data->last_retrieved_frame + p_data->stride_length; + data_frame = data->last_retrieved_frame + data->stride_length; } else { - data_frame = p_data->first_frame_with_data; + data_frame = data->first_frame_with_data; } frame_diff = data_frame - current_frame; if(frame_diff < 0) @@ -19325,8 +17604,8 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_dat } for(i = 0; i < frame_set->n_data_blocks; i++) { - np_data = &frame_set->tr_data[i]; - block_id = np_data->block_id; + data = &frame_set->tr_data[i]; + block_id = data->block_id; if(n_requested_data_block_ids > 0) { @@ -19345,8 +17624,8 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_dat } } - if(!read_all && (np_data->last_retrieved_frame < frame_set->first_frame || - np_data->last_retrieved_frame >= + if(!read_all && (data->last_retrieved_frame < frame_set->first_frame || + data->last_retrieved_frame >= frame_set->first_frame + frame_set->n_frames)) { stat = tng_frame_set_read_current_only_data_from_block_id(tng_data, @@ -19363,13 +17642,13 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_dat } } if(frame_set->first_frame != current_frame && - np_data->last_retrieved_frame >= 0) + data->last_retrieved_frame >= 0) { - data_frame = np_data->last_retrieved_frame + np_data->stride_length; + data_frame = data->last_retrieved_frame + data->stride_length; } else { - data_frame = np_data->first_frame_with_data; + data_frame = data->first_frame_with_data; } frame_diff = data_frame - current_frame; if(frame_diff < 0) @@ -19421,7 +17700,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_next_frame_present_dat /* tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_all_data_block_types_get - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, int64_t *n_data_blocks, int64_t **data_block_ids, char ***data_block_names, @@ -19440,14 +17719,13 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_all_data_block_types_g 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 = ftello(tng_data->input_file); - - if(!tng_data->input_file_len) + if(tng_input_file_init(tng_data) != TNG_SUCCESS) { - fseeko(tng_data->input_file, 0, SEEK_END); - tng_data->input_file_len = ftello(tng_data->input_file); + return(TNG_CRITICAL); } + orig_file_pos = ftello(tng_data->input_file); + fseeko(tng_data->input_file, 0, SEEK_SET); file_pos = 0; @@ -19472,7 +17750,7 @@ tng_function_status DECLSPECDLLEXPORT tng_util_trajectory_all_data_block_types_g } */ tng_function_status DECLSPECDLLEXPORT tng_util_prepare_append_after_frame - (tng_trajectory_t tng_data, + (const tng_trajectory_t tng_data, const int64_t prev_frame) { tng_function_status stat; @@ -19496,3 +17774,46 @@ tng_function_status DECLSPECDLLEXPORT tng_util_prepare_append_after_frame return(TNG_SUCCESS); } + +tng_function_status DECLSPECDLLEXPORT tng_util_num_frames_with_data_of_block_id_get + (const tng_trajectory_t tng_data, + const int64_t block_id, + int64_t *n_frames) +{ + int64_t curr_file_pos, first_frame_set_file_pos, curr_n_frames; + tng_function_status stat; + + TNG_ASSERT(tng_data, "TNG library: Trajectory container not properly setup."); + + *n_frames = 0; + + if(tng_input_file_init(tng_data) != TNG_SUCCESS) + { + return(TNG_CRITICAL); + } + + first_frame_set_file_pos = tng_data->first_trajectory_frame_set_input_file_pos; + curr_file_pos = ftello(tng_data->input_file); + fseeko(tng_data->input_file, first_frame_set_file_pos, SEEK_SET); + + stat = tng_frame_set_n_frames_of_data_block_get(tng_data, block_id, &curr_n_frames); + + while(stat == TNG_SUCCESS && tng_data->current_trajectory_frame_set.next_frame_set_file_pos != -1) + { + *n_frames += curr_n_frames; + fseeko(tng_data->input_file, + tng_data->current_trajectory_frame_set.next_frame_set_file_pos, + SEEK_SET); + stat = tng_frame_set_n_frames_of_data_block_get(tng_data, block_id, &curr_n_frames); + } + if(stat == TNG_SUCCESS) + { + *n_frames += curr_n_frames; + } + fseeko(tng_data->input_file, curr_file_pos, SEEK_SET); + if(stat == TNG_CRITICAL) + { + return(TNG_CRITICAL); + } + return(TNG_SUCCESS); +} diff --git a/src/external/tng_io/src/tests/md_openmp.c b/src/external/tng_io/src/tests/md_openmp.c index aac8b3b7bd..d500167e15 100644 --- a/src/external/tng_io/src/tests/md_openmp.c +++ b/src/external/tng_io/src/tests/md_openmp.c @@ -1,11 +1,11 @@ #ifdef TNG_BUILD_OPENMP_EXAMPLES +#include "tng/tng_io.h" #include #include #include #include #include -#include "tng/tng_io.h" int main (); void compute ( int np, int nd, double pos[], double vel[], diff --git a/src/external/tng_io/src/tests/md_openmp_util.c b/src/external/tng_io/src/tests/md_openmp_util.c index 9fe6c91b60..11a7fa0c70 100644 --- a/src/external/tng_io/src/tests/md_openmp_util.c +++ b/src/external/tng_io/src/tests/md_openmp_util.c @@ -1,11 +1,11 @@ #ifdef TNG_BUILD_OPENMP_EXAMPLES +#include "tng/tng_io.h" #include #include #include #include #include -#include "tng/tng_io.h" int main (); void compute ( int np, int nd, float pos[], float vel[], diff --git a/src/external/tng_io/src/tests/tng_io_read_pos.c b/src/external/tng_io/src/tests/tng_io_read_pos.c index b29cec7cd1..8e3d266fcc 100644 --- a/src/external/tng_io/src/tests/tng_io_read_pos.c +++ b/src/external/tng_io/src/tests/tng_io_read_pos.c @@ -9,13 +9,14 @@ * modify it under the terms of the Revised BSD License. */ +#include "tng/tng_io.h" + #ifdef USE_STD_INTTYPES_H #include #endif #include #include -#include "tng/tng_io.h" int main(int argc, char **argv) { diff --git a/src/external/tng_io/src/tests/tng_io_read_pos_util.c b/src/external/tng_io/src/tests/tng_io_read_pos_util.c index b237dad03d..699f52db87 100644 --- a/src/external/tng_io/src/tests/tng_io_read_pos_util.c +++ b/src/external/tng_io/src/tests/tng_io_read_pos_util.c @@ -11,13 +11,14 @@ * modify it under the terms of the Revised BSD License. */ +#include "tng/tng_io.h" + #ifdef USE_STD_INTTYPES_H #include #endif #include #include -#include "tng/tng_io.h" int main(int argc, char **argv) { diff --git a/src/external/tng_io/src/tests/tng_io_testing.c b/src/external/tng_io/src/tests/tng_io_testing.c index e1e2726db1..28f8f4777e 100644 --- a/src/external/tng_io/src/tests/tng_io_testing.c +++ b/src/external/tng_io/src/tests/tng_io_testing.c @@ -9,21 +9,37 @@ * modify it under the terms of the Revised BSD License. */ +#include "tng/tng_io.h" + #ifdef USE_STD_INTTYPES_H #include #endif #include #include -#include "tng/tng_io.h" +#include #include "tng/version.h" +#define BOX_SHAPE_X 150.0 +#define BOX_SHAPE_Y 145.5 +#define BOX_SHAPE_Z 155.5 +#define N_FRAME_SETS 100 +#define MEDIUM_STRIDE_LEN 5 +#define LONG_STRIDE_LEN 25 +#define TIME_PER_FRAME 2e-15 +#define COMPRESSION_PRECISION 1000 +#define USER_NAME "USER 1" +#define PROGRAM_NAME "tng_testing" +#define COMPUTER_NAME "Unknown computer" +#define FORCEFIELD_NAME "No forcefield" + static tng_function_status tng_test_setup_molecules(tng_trajectory_t traj) { tng_molecule_t molecule; tng_chain_t chain; tng_residue_t residue; tng_atom_t atom; + tng_bond_t bond; int64_t cnt; tng_molecule_add(traj, "water", &molecule); @@ -41,8 +57,15 @@ static tng_function_status tng_test_setup_molecules(tng_trajectory_t traj) { return(TNG_CRITICAL); } + tng_molecule_bond_add(traj, molecule, 0, 1, &bond); + tng_molecule_bond_add(traj, molecule, 0, 2, &bond); tng_molecule_cnt_set(traj, molecule, 200); tng_molecule_cnt_get(traj, molecule, &cnt); + + if(cnt != 200) + { + return(TNG_CRITICAL); + } /* printf("Created %"PRId64" %s molecules.\n", cnt, molecule->name); */ /* traj->molecule_cnt_list[traj->n_molecules-1] = 5; @@ -106,50 +129,353 @@ static tng_function_status tng_test_setup_molecules(tng_trajectory_t traj) return(TNG_SUCCESS); } +static tng_function_status tng_test_molecules(tng_trajectory_t traj) +{ + tng_molecule_t molecule, molecule_new; + tng_chain_t chain; + tng_residue_t residue; + tng_atom_t atom; + int64_t cnt, *bonds_to, *bonds_from; + char var_atoms, str[TNG_MAX_STR_LEN]; + tng_function_status stat; + + stat = tng_num_molecule_types_get(traj, &cnt); + if(stat != TNG_SUCCESS || cnt != 1) + { + printf("Molecule reading error. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + + stat = tng_num_molecules_get(traj, &cnt); + if(stat != TNG_SUCCESS || cnt != 200) + { + printf("Molecule reading error. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + + stat = tng_num_particles_variable_get(traj, &var_atoms); + if(stat != TNG_SUCCESS || var_atoms) + { + printf("Molecule reading error. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + + stat = tng_molecule_of_index_get(traj, 0, &molecule); + if(stat != TNG_SUCCESS) + { + printf("Cannot find molecule. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_molecule_find(traj, "water", -1, &molecule); + if(stat != TNG_SUCCESS) + { + printf("Cannot find molecule. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat =tng_molecule_name_get(traj, molecule, str, TNG_MAX_STR_LEN); + if(stat != TNG_SUCCESS) + { + printf("Cannot get molecule name. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_molecule_num_chains_get(traj, molecule, &cnt); + if(stat != TNG_SUCCESS || cnt != 1) + { + printf("Cannot get number of chains in molecule. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + stat = tng_molecule_chain_of_index_get(traj, molecule, 0, &chain); + if(stat != TNG_SUCCESS) + { + printf("Cannot get chain in molecule. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_molecule_chain_find(traj, molecule, "W", -1, &chain); + if(stat != TNG_SUCCESS) + { + printf("Cannot get chain in molecule. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_molecule_num_residues_get(traj, molecule, &cnt); + if(stat != TNG_SUCCESS || cnt != 1) + { + printf("Cannot get number of residues in molecule. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + stat = tng_molecule_residue_of_index_get(traj, molecule, 0, &residue); + if(stat != TNG_SUCCESS) + { + printf("Cannot get residue in molecule. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_molecule_num_atoms_get(traj, molecule, &cnt); + if(stat != TNG_SUCCESS || cnt != 3) + { + printf("Cannot get number of atoms in molecule. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + stat = tng_molecule_atom_of_index_get(traj, molecule, 0, &atom); + if(stat != TNG_SUCCESS) + { + printf("Cannot get atom in molecule. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_molecule_atom_find(traj, molecule, "O", -1, &atom); + if(stat != TNG_SUCCESS) + { + printf("Cannot get atom in molecule. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + + stat =tng_chain_name_get(traj, chain, str, TNG_MAX_STR_LEN); + if(stat != TNG_SUCCESS) + { + printf("Cannot get name of chain. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_chain_num_residues_get(traj, chain, &cnt); + if(stat != TNG_SUCCESS || cnt != 1) + { + printf("Cannot get number of residues in chain. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + stat = tng_chain_residue_of_index_get(traj, chain, 0, &residue); + if(stat != TNG_SUCCESS) + { + printf("Cannot get residue in chain. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_chain_residue_find(traj, chain, "WAT", -1, &residue); + if(stat != TNG_SUCCESS) + { + printf("Cannot get residue in chain. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + + stat = tng_residue_name_get(traj, residue, str, TNG_MAX_STR_LEN); + if(stat != TNG_SUCCESS) + { + printf("Cannot get name of residue. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_residue_num_atoms_get(traj, residue, &cnt); + if(stat != TNG_SUCCESS || cnt != 3) + { + printf("Cannot get number of atoms in residue. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + stat = tng_residue_atom_of_index_get(traj, residue, 0, &atom); + if(stat != TNG_SUCCESS) + { + printf("Cannot get residue of atom. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + + stat = tng_atom_name_get(traj, atom, str, TNG_MAX_STR_LEN); + if(stat != TNG_SUCCESS) + { + printf("Cannot get name of atom. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_atom_type_get(traj, atom, str, TNG_MAX_STR_LEN); + if(stat != TNG_SUCCESS) + { + printf("Cannot get atom type of atom. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + + stat = tng_molecule_id_of_particle_nr_get(traj, 0, &cnt); + if(stat != TNG_SUCCESS || cnt != 1) + { + printf("Cannot get molecule id of atom. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + stat = tng_residue_id_of_particle_nr_get(traj, 0, &cnt); + if(stat != TNG_SUCCESS || cnt != 0) + { + printf("Cannot get residue id of atom. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + stat = tng_global_residue_id_of_particle_nr_get(traj, 599, &cnt); + if(stat != TNG_SUCCESS || cnt != 199) + { + printf("Cannot get global residue id of atom. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + stat = tng_molecule_name_of_particle_nr_get(traj, 0, str, TNG_MAX_STR_LEN); + if(stat != TNG_SUCCESS) + { + printf("Cannot get molecule name of atom. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_chain_name_of_particle_nr_get(traj, 0, str, TNG_MAX_STR_LEN); + if(stat != TNG_SUCCESS) + { + printf("Cannot get chain name of atom. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_residue_name_of_particle_nr_get(traj, 0, str, TNG_MAX_STR_LEN); + if(stat != TNG_SUCCESS) + { + printf("Cannot get residue name of atom. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_atom_name_of_particle_nr_get(traj, 0, str, TNG_MAX_STR_LEN); + if(stat != TNG_SUCCESS) + { + printf("Cannot get atom name of atom. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + + stat = tng_molecule_alloc(traj, &molecule_new); + if(stat != TNG_SUCCESS) + { + printf("Cannot setup new molecule. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_molecule_name_set(traj, molecule_new, "TEST"); + if(stat != TNG_SUCCESS) + { + printf("Cannot set name of new molecule. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_molecule_existing_add(traj, &molecule_new); + if(stat != TNG_SUCCESS) + { + printf("Cannot add new molecule to molecule system. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + + stat = tng_molsystem_bonds_get(traj, &cnt, &bonds_from, &bonds_to); + if(stat != TNG_SUCCESS || cnt != 400) + { + printf("Cannot get bonds in molecule system. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + + free(bonds_from); + free(bonds_to); + + return(TNG_SUCCESS); +} + static tng_function_status tng_test_read_and_write_file - (tng_trajectory_t traj) + (tng_trajectory_t traj, const char hash_mode) { + char file_name[TNG_MAX_STR_LEN]; tng_function_status stat; - stat = tng_file_headers_read(traj, TNG_USE_HASH); - if(stat == TNG_CRITICAL) + stat = tng_input_file_get(traj, file_name, TNG_MAX_STR_LEN); + if(stat != TNG_SUCCESS) { + printf("Could not get name of input file. %s: %d\n", + __FILE__, __LINE__); return(stat); } - stat = tng_file_headers_write(traj, TNG_USE_HASH); - if(stat == TNG_CRITICAL) + stat = tng_output_file_get(traj, file_name, TNG_MAX_STR_LEN); + if(stat != TNG_SUCCESS) + { + printf("Could not get name of output file. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + + stat = tng_file_headers_read(traj, hash_mode); + if(stat != TNG_SUCCESS) + { + printf("Could not read headers. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_file_headers_write(traj, hash_mode); + if(stat != TNG_SUCCESS) { + printf("Could not write headers. %s: %d\n", + __FILE__, __LINE__); return(stat); } while(stat == TNG_SUCCESS) { - stat = tng_frame_set_read_next(traj, TNG_USE_HASH); - if(stat != TNG_SUCCESS) + stat = tng_frame_set_read_next(traj, hash_mode); + if(stat == TNG_CRITICAL) { + printf("Could not read frame set. %s: %d\n", + __FILE__, __LINE__); return(stat); } - stat = tng_frame_set_write(traj, TNG_USE_HASH); + if(stat == TNG_FAILURE) + { + return(TNG_SUCCESS); + } + stat = tng_frame_set_write(traj, hash_mode); } return(stat); } -static tng_function_status tng_test_write_and_read_traj(tng_trajectory_t *traj) +static tng_function_status tng_test_write_and_read_traj(tng_trajectory_t *traj, + const char hash_mode) { - int i, j, k, nr, cnt; + int i, j, k, nr, cnt, dependency; float *data, *molpos, *charges; int64_t mapping[300], n_particles, n_frames_per_frame_set, tot_n_mols; + int64_t codec_id; + int64_t dist_exp = -9, temp_int, temp_int2; // int64_t frame_nr; - double box_shape[9]; + double box_shape[9], temp_double; char atom_type[16], annotation[128]; + char temp_str[TNG_MAX_STR_LEN]; + tng_trajectory_frame_set_t frame_set; tng_function_status stat = TNG_SUCCESS; - tng_medium_stride_length_set(*traj, 10); - tng_long_stride_length_set(*traj, 100); + tng_medium_stride_length_set(*traj, MEDIUM_STRIDE_LEN); + tng_long_stride_length_set(*traj, LONG_STRIDE_LEN); + + tng_first_user_name_set(*traj, USER_NAME); + tng_first_program_name_set(*traj, PROGRAM_NAME); + tng_first_computer_name_set(*traj, COMPUTER_NAME); + tng_forcefield_name_set(*traj, FORCEFIELD_NAME); - tng_first_user_name_set(*traj, "User1"); - tng_first_program_name_set(*traj, "tng_testing"); + tng_compression_precision_set(*traj, COMPRESSION_PRECISION); + + tng_distance_unit_exponential_set(*traj, dist_exp); + + tng_time_per_frame_set(*traj, TIME_PER_FRAME); /* Create molecules */ if(tng_test_setup_molecules(*traj) == TNG_CRITICAL) @@ -160,9 +486,9 @@ static tng_function_status tng_test_write_and_read_traj(tng_trajectory_t *traj) /* Set the box shape */ box_shape[1] = box_shape[2] = box_shape[3] = box_shape[5] = box_shape[6] = box_shape[7] = 0; - box_shape[0] = 150.0; - box_shape[4] = 145.5; - box_shape[8] = 155.5; + box_shape[0] = BOX_SHAPE_X; + box_shape[4] = BOX_SHAPE_Y; + box_shape[8] = BOX_SHAPE_Z; if(tng_data_block_add(*traj, TNG_TRAJ_BOX_SHAPE, "BOX SHAPE", TNG_DOUBLE_DATA, TNG_NON_TRAJECTORY_BLOCK, 1, 9, 1, TNG_UNCOMPRESSED, box_shape) == TNG_CRITICAL) @@ -195,7 +521,8 @@ static tng_function_status tng_test_write_and_read_traj(tng_trajectory_t *traj) if(stat == TNG_CRITICAL) { free(charges); - printf("Failed setting partial charges.\n"); + printf("Failed setting partial charges. %s: %d\n", + __FILE__, __LINE__); return(TNG_CRITICAL); } @@ -206,7 +533,8 @@ static tng_function_status tng_test_write_and_read_traj(tng_trajectory_t *traj) free(charges); if(stat != TNG_SUCCESS) { - printf("Failed adding partial charges\n"); + printf("Failed adding partial charges. %s: %d\n", + __FILE__, __LINE__); return(TNG_CRITICAL); } @@ -218,14 +546,16 @@ static tng_function_status tng_test_write_and_read_traj(tng_trajectory_t *traj) TNG_NON_TRAJECTORY_BLOCK, 1, 1, 1, TNG_UNCOMPRESSED, annotation) != TNG_SUCCESS) { - printf("Failed adding details annotation data block.\n"); + printf("Failed adding details annotation data block. %s: %d\n", + __FILE__, __LINE__); return(TNG_CRITICAL); } /* Write file headers (includes non trajectory data blocks */ - if(tng_file_headers_write(*traj, TNG_SKIP_HASH) == TNG_CRITICAL) + if(tng_file_headers_write(*traj, hash_mode) == TNG_CRITICAL) { - printf("Cannot write file headers.\n"); + printf("Cannot write file headers. %s: %d\n", + __FILE__, __LINE__); } @@ -253,10 +583,18 @@ static tng_function_status tng_test_write_and_read_traj(tng_trajectory_t *traj) molpos[nr+2] = 100.0 * rand() / (RAND_MAX + 1.0); } - /* Generate 200 frame sets - each with 100 frames (by default) */ - for(i = 0; i < 200; i++) + /* Generate frame sets - each with 100 frames (by default) */ + for(i = 0; i < N_FRAME_SETS; i++) { cnt = 0; + if(i < N_FRAME_SETS/2) + { + codec_id = TNG_GZIP_COMPRESSION; + } + else + { + codec_id = TNG_TNG_COMPRESSION; + } for(j = 0; j < n_frames_per_frame_set; j++) { for(k = 0; k < tot_n_mols; k++) @@ -278,8 +616,8 @@ static tng_function_status tng_test_write_and_read_traj(tng_trajectory_t *traj) data[cnt++] = molpos[nr + 2] - 1; } } - if(tng_frame_set_new(*traj, i * n_frames_per_frame_set, - n_frames_per_frame_set) != TNG_SUCCESS) + if(tng_frame_set_with_time_new(*traj, i * n_frames_per_frame_set, + n_frames_per_frame_set, 2e-15 * (i*n_frames_per_frame_set)) != TNG_SUCCESS) { printf("Error creating frame set %d. %s: %d\n", i, __FILE__, __LINE__); @@ -349,7 +687,7 @@ static tng_function_status tng_test_write_and_read_traj(tng_trajectory_t *traj) n_frames_per_frame_set, 3, 1, 0, n_particles, /* TNG_UNCOMPRESSED, */ - TNG_GZIP_COMPRESSION, + codec_id, data) != TNG_SUCCESS) { printf("Error adding data. %s: %d\n", __FILE__, __LINE__); @@ -358,7 +696,7 @@ static tng_function_status tng_test_write_and_read_traj(tng_trajectory_t *traj) return(TNG_CRITICAL); } /* Write the frame set */ - if(tng_frame_set_write(*traj, TNG_SKIP_HASH) != TNG_SUCCESS) + if(tng_frame_set_write(*traj, hash_mode) != TNG_SUCCESS) { printf("Error writing frame set. %s: %d\n", __FILE__, __LINE__); free(molpos); @@ -367,125 +705,214 @@ static tng_function_status tng_test_write_and_read_traj(tng_trajectory_t *traj) } } - /* Write two more frame sets one frame at a time */ + free(molpos); + free(data); + + tng_trajectory_destroy(traj); + tng_trajectory_init(traj); + tng_input_file_set(*traj, TNG_EXAMPLE_FILES_DIR "tng_test.tng"); + + stat = tng_file_headers_read(*traj, hash_mode); - /* Make a new frame set - if always using the same mapping blocks - * it is not necessary to explicitly add a new frame set - it will - * be added automatically when adding data for a frame */ -/* if(tng_frame_set_new(*traj, i * n_frames_per_frame_set, - n_frames_per_frame_set) != TNG_SUCCESS) + tng_first_user_name_get(*traj, temp_str, TNG_MAX_STR_LEN); + if(strcmp(USER_NAME, temp_str) != 0) { - printf("Error creating frame set %d. %s: %d\n", - i, __FILE__, __LINE__); - free(molpos); - free(data); - return(TNG_CRITICAL); + printf("User name does not match when reading written file. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); } - frame_nr = i * n_frames_per_frame_set; + tng_first_program_name_get(*traj, temp_str, TNG_MAX_STR_LEN); + if(strcmp(PROGRAM_NAME, temp_str) != 0) + { + printf("Program name does not match when reading written file. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } - for(k=0; k<300; k++) + tng_first_computer_name_get(*traj, temp_str, TNG_MAX_STR_LEN); + if(strcmp(COMPUTER_NAME, temp_str) != 0) { - mapping[k]=k; + printf("Computer name does not match when reading written file. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); } - *//* Just use two particle mapping blocks in this frame set *//* - if(tng_particle_mapping_add(*traj, 0, 300, mapping) != TNG_SUCCESS) + + tng_forcefield_name_get(*traj, temp_str, TNG_MAX_STR_LEN); + if(strcmp(FORCEFIELD_NAME, temp_str) != 0) { - printf("Error creating particle mapping. %s: %d\n", - __FILE__, __LINE__); - free(molpos); - free(data); - return(TNG_CRITICAL); + printf("Forcefield name does not match when reading written file. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); } - for(k=0; k<300; k++) + + tng_medium_stride_length_get(*traj, &temp_int); + if(temp_int != MEDIUM_STRIDE_LEN) { - mapping[k]=599-k; + printf("Stride length does not match when reading written file. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); } - if(tng_particle_mapping_add(*traj, 300, 300, mapping) != TNG_SUCCESS) + + tng_long_stride_length_get(*traj, &temp_int); + if(temp_int != LONG_STRIDE_LEN) { - printf("Error creating particle mapping. %s: %d\n", - __FILE__, __LINE__); - free(molpos); - free(data); - return(TNG_CRITICAL); + printf("Stride length does not match when reading written file. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); } - *//* Add the data block to the current frame set *//* - if(tng_particle_data_block_add(*traj, TNG_TRAJ_POSITIONS, - "POSITIONS", - TNG_FLOAT_DATA, - TNG_TRAJECTORY_BLOCK, - n_frames_per_frame_set, 3, - 1, 0, n_particles, - TNG_UNCOMPRESSED, - 0) != TNG_SUCCESS) + tng_compression_precision_get(*traj, &temp_double); + if(temp_double != COMPRESSION_PRECISION) { - printf("Error adding data. %s: %d\n", __FILE__, __LINE__); - free(molpos); - free(data); - return(TNG_CRITICAL); + printf("Compression precision does not match when reading written file. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); } - *//* Write the frame set to disk *//* - if(tng_frame_set_write(*traj, TNG_SKIP_HASH) != TNG_SUCCESS) + tng_distance_unit_exponential_get(*traj, &temp_int); + if(temp_int != dist_exp) { - printf("Error writing frame set. %s: %d\n", __FILE__, __LINE__); - free(molpos); - free(data); - return(TNG_CRITICAL); + printf("Distance unit exponential does not match when reading written file. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); } - *//* Write particle data to disk - one frame at a time *//* - for(i = 0; i < n_frames_per_frame_set * 2; i++) + stat = tng_test_molecules(*traj); + if(stat != TNG_SUCCESS) { - for(j = 0; j < 2; j++) + return(stat); + } + + i = 0; + while(stat == TNG_SUCCESS) + { + stat = tng_frame_set_read_next(*traj, hash_mode); + tng_current_frame_set_get(*traj, &frame_set); + tng_frame_set_prev_frame_set_file_pos_get(*traj, frame_set, &temp_int); + tng_frame_set_next_frame_set_file_pos_get(*traj, frame_set, &temp_int2); + if(i > 0) { - cnt = 0; - for(k = 0; k < tot_n_mols/2; k++) + if(temp_int == -1) { - nr = k * 3; - *//* Move -1 to 1 *//* - molpos[nr] += 2 * (rand() / (RAND_MAX + 1.0)) - 1; - molpos[nr+1] += 2 * (rand() / (RAND_MAX + 1.0)) - 1; - molpos[nr+2] += 2 * (rand() / (RAND_MAX + 1.0)) - 1; - - data[cnt++] = molpos[nr]; - data[cnt++] = molpos[nr + 1]; - data[cnt++] = molpos[nr + 2]; - data[cnt++] = molpos[nr] + 1; - data[cnt++] = molpos[nr + 1] + 1; - data[cnt++] = molpos[nr + 2] + 1; - data[cnt++] = molpos[nr] - 1; - data[cnt++] = molpos[nr + 1] - 1; - data[cnt++] = molpos[nr + 2] - 1; + printf("File position of previous frame set not correct. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); } - if(tng_frame_particle_data_write(*traj, frame_nr + i, - TNG_TRAJ_POSITIONS, j * 300, 300, - data, TNG_SKIP_HASH) != TNG_SUCCESS) + } + else if(temp_int != -1) + { + printf("File position of previous frame set not correct. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + if(i < N_FRAME_SETS -1) + { + if(temp_int2 == -1) { - printf("Error adding data. %s: %d\n", __FILE__, __LINE__); - free(molpos); - free(data); - return(TNG_CRITICAL); + printf("File position of next frame set not correct. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); } } + else if(temp_int2 != -1) + { + printf("File position of previous next set not correct. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + i++; + } + if(stat == TNG_CRITICAL) + { + return(stat); } -*/ - free(molpos); - free(data); - tng_trajectory_destroy(traj); - tng_trajectory_init(traj); - tng_input_file_set(*traj, TNG_EXAMPLE_FILES_DIR "tng_test.tng"); + tng_time_per_frame_get(*traj, &temp_double); + if(fabs(TIME_PER_FRAME - temp_double) > 0.000001) + { + printf("Time per frame does not match when reading written file. %s: %d\n", + __FILE__, __LINE__); + printf("Value: %e, expected value: %e\n", temp_double, TIME_PER_FRAME); + return(TNG_FAILURE); + } - stat = tng_file_headers_read(*traj, TNG_SKIP_HASH); + stat = tng_frame_set_nr_find(*traj, (int64_t)(0.30*N_FRAME_SETS)); + if(stat != TNG_SUCCESS) + { + printf("Could not find frame set %"PRId64". %s: %d\n", (int64_t)0.30*N_FRAME_SETS, + __FILE__, __LINE__); + return(stat); + } - while(stat == TNG_SUCCESS) + stat = tng_frame_set_nr_find(*traj, (int64_t)(0.75*N_FRAME_SETS)); + if(stat != TNG_SUCCESS) { - stat = tng_frame_set_read_next(*traj, TNG_SKIP_HASH); + printf("Could not find frame set %"PRId64". %s: %d\n", (int64_t)0.75*N_FRAME_SETS, + __FILE__, __LINE__); + return(stat); } - return(stat); + tng_current_frame_set_get(*traj, &frame_set); + tng_frame_set_frame_range_get(*traj, frame_set, &temp_int, &temp_int2); + if(temp_int != 75 * n_frames_per_frame_set) + { + printf("Unexpected first frame in frame set. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + + stat = tng_frame_set_read_current_only_data_from_block_id(*traj, hash_mode, TNG_TRAJ_POSITIONS); + if(stat != TNG_SUCCESS) + { + printf("Cannot read positions in current frame set. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + stat = tng_frame_set_read_next_only_data_from_block_id(*traj, hash_mode, TNG_TRAJ_POSITIONS); + if(stat != TNG_SUCCESS) + { + printf("Cannot read positions in next frame set. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + stat = tng_data_block_name_get(*traj, TNG_TRAJ_POSITIONS, temp_str, TNG_MAX_STR_LEN); + if(stat != TNG_SUCCESS || strcmp("POSITIONS", temp_str) != 0) + { + printf("Cannot get name of data block or unexpected name. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + stat = tng_data_block_name_get(*traj, TNG_TRAJ_FORCES, temp_str, TNG_MAX_STR_LEN); + if(stat != TNG_FAILURE) + { + printf("Trying to retrieve name of non-existent data block did not return failure. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + stat = tng_data_block_dependency_get(*traj, TNG_TRAJ_POSITIONS, &dependency); + if(stat != TNG_SUCCESS || dependency != TNG_FRAME_DEPENDENT + TNG_PARTICLE_DEPENDENT) + { + printf("Cannot get dependency of data block or unexpected dependency. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + stat = tng_data_block_num_values_per_frame_get(*traj, TNG_TRAJ_POSITIONS, &temp_int); + if(stat != TNG_SUCCESS || temp_int != 3) + { + printf("Cannot get number of values per frame of data block or unexpected value. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + stat = tng_data_get_stride_length(*traj, TNG_TRAJ_POSITIONS, 100, &temp_int); + if(stat != TNG_SUCCESS || temp_int != 1) + { + printf("Cannot get stride length of data block or unexpected value. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + + return(TNG_SUCCESS); } /* This test relies on knowing that the box shape is stored as double */ @@ -502,18 +929,13 @@ tng_function_status tng_test_get_box_data(tng_trajectory_t traj) return(TNG_CRITICAL); } -/* -// int64_t i, j; -// printf("Box shape:"); -// for(i=0; i 0.000001) + { + printf("Unexpected value in box shape. %s: %d\n", __FILE__, __LINE__); + return(TNG_FAILURE); + } + tng_data_values_free(traj, values, n_frames, n_values_per_frame, type); return(TNG_SUCCESS); @@ -522,9 +944,10 @@ tng_function_status tng_test_get_box_data(tng_trajectory_t traj) /* This test relies on knowing that the positions are stored as float * and that the data is not sparse (i.e. as many frames in the data * as in the frame set */ -tng_function_status tng_test_get_positions_data(tng_trajectory_t traj) +tng_function_status tng_test_get_positions_data(tng_trajectory_t traj, + const char hash_mode) { - int64_t n_frames, n_particles, n_values_per_frame; + int64_t i, j, k, n_frames, n_particles, n_values_per_frame; union data_values ***values = 0; char type; @@ -536,57 +959,317 @@ tng_function_status tng_test_get_positions_data(tng_trajectory_t traj) return(TNG_CRITICAL); } -/* -// int64_t i, j, k; -// struct tng_trajectory_frame_set *frame_set = -// &traj->current_trajectory_frame_set; -// for(i = 0; ifirst_frame + i); -// for(j = 0; j 500) + { + printf("Coordinates not in range. %s: %d\n", + __FILE__, __LINE__); + tng_particle_data_values_free(traj, values, n_frames, n_particles, + n_values_per_frame, type); + return(TNG_FAILURE); + } + } // printf("\n"); -// } -// } -*/ + } + } + + if(tng_particle_data_interval_get(traj, TNG_TRAJ_POSITIONS, 111000, 111499, + hash_mode, &values, &n_particles, + &n_values_per_frame, &type) == TNG_SUCCESS) + { + printf("Getting particle positions succeeded when it should have failed. %s: %d\n", + __FILE__, __LINE__); + return(TNG_CRITICAL); + } + + if(tng_particle_data_interval_get(traj, TNG_TRAJ_POSITIONS, 1000, 1050, + hash_mode, &values, &n_particles, + &n_values_per_frame, &type) != TNG_SUCCESS) + { + printf("Failed getting particle positions. %s: %d\n", __FILE__, __LINE__); + return(TNG_CRITICAL); + } + + for(i = 0; i < 50; i++) + { +// printf("%"PRId64"\n", i); + for(j = 0; j < n_particles; j++) + { + for(k = 0; k < n_values_per_frame; k++) + { +// printf("%f ", values[i][j][k].f); + if(values[i][j][k].f < -500 || values[i][j][k].f > 500) + { + printf("Coordinates not in range. %s: %d\n", + __FILE__, __LINE__); + tng_particle_data_values_free(traj, values, n_frames, n_particles, + n_values_per_frame, type); + return(TNG_FAILURE); + } + } +// printf("\n"); + } + } + tng_particle_data_values_free(traj, values, n_frames, n_particles, n_values_per_frame, type); - values = 0; + return(TNG_SUCCESS); +} - tng_particle_data_interval_get(traj, TNG_TRAJ_POSITIONS, 11000, 11499, - TNG_SKIP_HASH, &values, &n_particles, - &n_values_per_frame, &type); +tng_function_status tng_test_utility_functions(tng_trajectory_t traj, const char hash_mode) +{ + tng_function_status stat; + int64_t n_particles, i, j, k, codec_id, n_frames, n_frames_per_frame_set; + int64_t n_frames_to_read=30, stride_len, next_frame, n_blocks, *block_ids = 0; + double time, multiplier; + float *positions = 0; - /* Here the particle positions can be printed */ + stat = tng_util_trajectory_open(TNG_EXAMPLE_FILES_DIR "tng_test.tng", 'r', &traj); + if(stat != TNG_SUCCESS) + { + return(stat); + } - tng_particle_data_values_free(traj, values, 500, n_particles, - n_values_per_frame, type); + stat = tng_util_time_of_frame_get(traj, 50, &time); + if(stat != TNG_SUCCESS || fabs(time - 100e-13) > 0.000001) + { + printf("Unexpected time at frame 50. %s: %d\n", __FILE__, __LINE__); + printf("Value: %e, expected value: %e\n", time, 100e-13); + return(stat); + } + stat = tng_util_time_of_frame_get(traj, 100, &time); + if(stat != TNG_SUCCESS || fabs(time - 200e-13) > 0.000001) + { + printf("Unexpected time at frame 100. %s: %d\n", __FILE__, __LINE__); + printf("Value: %e, expected value: %e\n", time, 100e-13); + return(stat); + } + + tng_num_frames_per_frame_set_get(traj, &n_frames_per_frame_set); + + stat = tng_util_num_frames_with_data_of_block_id_get(traj, TNG_TRAJ_POSITIONS, &n_frames); + if(stat != TNG_SUCCESS || n_frames != n_frames_per_frame_set * N_FRAME_SETS) + { + printf("Unexpected number of frames with positions data. %s: %d\n", + __FILE__, __LINE__); + printf("Value: %"PRId64", expected value: %"PRId64"\n", n_frames, + n_frames_per_frame_set * N_FRAME_SETS); + return(stat); + } + + tng_num_frames_per_frame_set_get(traj, &n_frames_per_frame_set); + + stat = tng_util_num_frames_with_data_of_block_id_get(traj, TNG_TRAJ_POSITIONS, &n_frames); + if(stat != TNG_SUCCESS || n_frames != n_frames_per_frame_set * N_FRAME_SETS) + { + return(stat); + } + + tng_num_particles_get(traj, &n_particles); + + stat = tng_util_pos_read_range(traj, 1, n_frames_to_read, &positions, &stride_len); + if(stat != TNG_SUCCESS) + { + if(positions) + { + free(positions); + } + return(stat); + } + + for(i = 0; i < n_frames_to_read / stride_len; i++) + { + for(j = 0; j < n_particles; j++) + { + for(k = 0; k < 3; k++) + { + if(positions[i*n_particles + j*3 + k] < -500 || positions[i*n_particles + j*3 + k] > 500) + { + printf("Coordinates not in range. %s: %d\n", + __FILE__, __LINE__); + free(positions); + return(TNG_FAILURE); + } + } + } + } + + free(positions); + + stat=tng_util_trajectory_next_frame_present_data_blocks_find(traj, n_frames_to_read, + 0, 0, &next_frame, + &n_blocks, &block_ids); + if(block_ids) + { + free(block_ids); + } + if(stat != TNG_SUCCESS || n_blocks != 1 || next_frame != n_frames_to_read + stride_len) + { + printf("Unexpected data blocks in next frame. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + + stat = tng_util_frame_current_compression_get(traj, TNG_TRAJ_POSITIONS, &codec_id, &multiplier); + if(stat != TNG_SUCCESS || codec_id != TNG_GZIP_COMPRESSION) + { + printf("Could not get compression. %s: %d\n", + __FILE__, __LINE__); + return(TNG_FAILURE); + } + + stat = tng_util_trajectory_close(&traj); + if(stat != TNG_SUCCESS) + { + return(stat); + } return(TNG_SUCCESS); } -tng_function_status tng_test_append(tng_trajectory_t traj) +tng_function_status tng_test_append(tng_trajectory_t traj, const char hash_mode) { + char str[TNG_MAX_STR_LEN]; + int64_t n_frames, n_particles, i; + double time, *velocities; tng_function_status stat; stat = tng_util_trajectory_open(TNG_EXAMPLE_FILES_DIR "tng_test.tng", 'a', &traj); if(stat != TNG_SUCCESS) { + printf("Cannot open trajectory. %s: %d\n", + __FILE__, __LINE__); return(stat); } - tng_last_user_name_set(traj, "User2"); - tng_last_program_name_set(traj, "tng_testing"); - tng_file_headers_write(traj, TNG_USE_HASH); + stat = tng_last_user_name_set(traj, USER_NAME); + if(stat != TNG_SUCCESS) + { + printf("Cannot set last user name. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_last_user_name_get(traj, str, TNG_MAX_STR_LEN); + if(stat != TNG_SUCCESS) + { + printf("Cannot get last user name. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_last_program_name_set(traj, PROGRAM_NAME); + if(stat != TNG_SUCCESS) + { + printf("Cannot set last program name. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_last_program_name_get(traj, str, TNG_MAX_STR_LEN); + if(stat != TNG_SUCCESS) + { + printf("Cannot get last program name. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_last_computer_name_set(traj, "Still " COMPUTER_NAME); + if(stat != TNG_SUCCESS) + { + printf("Cannot set last computer name. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + stat = tng_last_computer_name_get(traj, str, TNG_MAX_STR_LEN); + if(stat != TNG_SUCCESS) + { + printf("Cannot get last computer name. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + + stat = tng_file_headers_write(traj, hash_mode); + if(stat != TNG_SUCCESS) + { + printf("Cannot write file headers. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + + tng_num_frames_get(traj, &n_frames); + tng_frame_set_of_frame_find(traj, n_frames - 1); + tng_util_time_of_frame_get(traj, n_frames - 1, &time); + time += TIME_PER_FRAME; + tng_num_particles_get(traj, &n_particles); + + velocities = malloc(sizeof(double) * n_particles * 3); + if(!velocities) + { + printf("Cannot allocate memory. %s: %d\n", + __FILE__, __LINE__); + return(TNG_CRITICAL); + } + + for(i = 0; i < n_particles * 3; i++) + { + velocities[i] = i; + } + + stat = tng_util_vel_with_time_double_write(traj, n_frames, time, velocities); + + free(velocities); + + stat = tng_util_trajectory_close(&traj); + + return(stat); +} + +tng_function_status tng_test_copy_container(tng_trajectory_t traj, const char hash_mode) +{ + tng_trajectory_t dest; + tng_function_status stat; + + stat = tng_util_trajectory_open(TNG_EXAMPLE_FILES_DIR "tng_test.tng", 'r', &traj); + if(stat != TNG_SUCCESS) + { + printf("Cannot open trajectory. %s: %d\n", + __FILE__, __LINE__); + return(stat); + } + + stat = tng_trajectory_init_from_src(traj, &dest); + if(stat != TNG_SUCCESS) + { + return(stat); + } + + stat = tng_molecule_system_copy(traj, dest); + if(stat != TNG_SUCCESS) + { + return(stat); + } stat = tng_util_trajectory_close(&traj); + if(stat != TNG_SUCCESS) + { + return(stat); + } + stat = tng_util_trajectory_close(&dest); return(stat); } @@ -594,28 +1277,29 @@ tng_function_status tng_test_append(tng_trajectory_t traj) int main() { tng_trajectory_t traj; - tng_function_status stat; char time_str[TNG_MAX_DATE_STR_LEN]; char version_str[TNG_MAX_STR_LEN]; + char hash_mode = TNG_USE_HASH; tng_version(traj, version_str, TNG_MAX_STR_LEN); + printf("Test version control:\t\t\t\t"); if(strncmp(TNG_VERSION, version_str, TNG_MAX_STR_LEN) == 0) { - printf("Test version control: \t\t\t\tSucceeded.\n"); + printf("Succeeded.\n"); } else { - printf("Test version control: \t\t\t\tFailed.\n"); + printf("Failed.\n"); } + printf("Test Init trajectory:\t\t\t\t"); if(tng_trajectory_init(&traj) != TNG_SUCCESS) { tng_trajectory_destroy(&traj); - printf("Test Init trajectory:\t\t\t\tFailed. %s: %d.\n", - __FILE__, __LINE__); + printf("Failed. %s: %d.\n", __FILE__, __LINE__); exit(1); } - printf("Test Init trajectory:\t\t\t\tSucceeded.\n"); + printf("Succeeded.\n"); tng_time_get_str(traj, time_str); @@ -624,107 +1308,101 @@ int main() tng_input_file_set(traj, TNG_EXAMPLE_FILES_DIR "tng_example.tng"); tng_output_file_set(traj, TNG_EXAMPLE_FILES_DIR "tng_example_out.tng"); - - if(tng_test_read_and_write_file(traj) == TNG_CRITICAL) + printf("Test Read and write file:\t\t\t"); + if(tng_test_read_and_write_file(traj, hash_mode) != TNG_SUCCESS) { - printf("Test Read and write file:\t\t\tFailed. %s: %d\n", - __FILE__, __LINE__); + printf("Failed. %s: %d\n", __FILE__, __LINE__); } else { - printf("Test Read and write file:\t\t\tSucceeded.\n"); + printf("Succeeded.\n"); } + printf("Test Get data:\t\t\t\t\t"); if(tng_test_get_box_data(traj) != TNG_SUCCESS) { - printf("Test Get data:\t\t\t\t\tFailed. %s: %d\n", - __FILE__, __LINE__); + printf("Failed. %s: %d\n", __FILE__, __LINE__); } else { - printf("Test Get data:\t\t\t\t\tSucceeded.\n"); + printf("Succeeded.\n"); } - if(tng_trajectory_destroy(&traj) == TNG_CRITICAL || - tng_trajectory_init(&traj) == TNG_CRITICAL) + printf("Test Destroy and init trajectory:\t\t"); + if(tng_trajectory_destroy(&traj) != TNG_SUCCESS || + tng_trajectory_init(&traj) != TNG_SUCCESS) { - printf("Test Destroy and init trajectory:\t\tFailed. %s: %d\n", - __FILE__, __LINE__); + printf("Failed. %s: %d\n", __FILE__, __LINE__); } else { - printf("Test Destroy and init trajectory:\t\tSucceeded.\n"); + printf("Succeeded.\n"); } tng_output_file_set(traj, TNG_EXAMPLE_FILES_DIR "tng_test.tng"); - if(tng_test_write_and_read_traj(&traj) == TNG_CRITICAL) + printf("Test Write and read file:\t\t\t"); + if(tng_test_write_and_read_traj(&traj, hash_mode) != TNG_SUCCESS) { - printf("Test Write and read file:\t\t\tFailed. %s: %d\n", - __FILE__, __LINE__); + printf("Failed. %s: %d\n", __FILE__, __LINE__); } else { - printf("Test Write and read file:\t\t\tSucceeded.\n"); + printf("Succeeded.\n"); } - if(tng_test_get_positions_data(traj) != TNG_SUCCESS) + printf("Test Get particle data:\t\t\t\t"); + if(tng_test_get_positions_data(traj, hash_mode) != TNG_SUCCESS) { - printf("Test Get particle data:\t\t\t\tFailed. %s: %d\n", + printf("Failed. %s: %d\n", __FILE__, __LINE__); } else { - printf("Test Get particle data:\t\t\t\tSucceeded.\n"); + printf("Succeeded.\n"); } - if(tng_trajectory_destroy(&traj) == TNG_CRITICAL) + printf("Test Destroy trajectory:\t\t\t"); + if(tng_trajectory_destroy(&traj) != TNG_SUCCESS) { - printf("Test Destroy trajectory:\t\t\tFailed. %s: %d.\n", - __FILE__, __LINE__); + printf("Failed. %s: %d.\n", __FILE__, __LINE__); exit(1); } else { - printf("Test Destroy trajectory:\t\t\tSucceeded.\n"); + printf("Succeeded.\n"); } - - stat = tng_util_trajectory_open(TNG_EXAMPLE_FILES_DIR "tng_test.tng", 'r', &traj); - - if(stat != TNG_SUCCESS) + printf("Test Utility functions:\t\t\t\t"); + if(tng_test_utility_functions(traj, hash_mode) != TNG_SUCCESS) { - printf("Test Utility function open:\t\t\tFailed. %s: %d.\n", - __FILE__, __LINE__); + printf("Failed. %s: %d.\n", __FILE__, __LINE__); exit(1); } else { - printf("Test Utility function open:\t\t\tSucceeded.\n"); + printf("Succeeded.\n"); } - stat = tng_util_trajectory_close(&traj); - if(stat != TNG_SUCCESS) + printf("Test Append:\t\t\t\t\t"); + if(tng_test_append(traj, hash_mode) != TNG_SUCCESS) { - printf("Test Utility function close:\t\t\tFailed. %s: %d.\n", - __FILE__, __LINE__); - exit(1); + printf("Failed. %s: %d.\n", __FILE__, __LINE__); } else { - printf("Test Utility function close:\t\t\tSucceeded.\n"); + printf("Succeeded.\n"); } - if(tng_test_append(traj) != TNG_SUCCESS) + printf("Test Copy trajectory container:\t\t\t"); + if(tng_test_copy_container(traj, hash_mode) != TNG_SUCCESS) { - printf("Test Append:\t\t\t\t\tFailed. %s: %d.\n", - __FILE__, __LINE__); - exit(1); + printf("Failed. %s: %d.\n", __FILE__, __LINE__); } else { - printf("Test Append:\t\t\t\t\tSucceeded.\n"); + printf("Succeeded.\n"); } printf("Tests finished\n"); diff --git a/src/external/tng_io/src/tests/tng_parallel_read.c b/src/external/tng_io/src/tests/tng_parallel_read.c index 44e8f796b7..c2ef2d6254 100644 --- a/src/external/tng_io/src/tests/tng_parallel_read.c +++ b/src/external/tng_io/src/tests/tng_parallel_read.c @@ -11,9 +11,10 @@ * modify it under the terms of the Revised BSD License. */ +#include "tng/tng_io.h" + #include #include -#include "tng/tng_io.h" /* N.B. this code is for testing parallel reading of trajectory frame sets. The -- 2.22.0