/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Copyright by The HDF Group.                                               *
 * All rights reserved.                                                      *
 *                                                                           *
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
 * terms governing use, modification, and redistribution, is contained in    *
 * the LICENSE file, which can be found at the root of the source code       *
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
 * If you do not have access to either file, you may request a copy from     *
 * help@hdfgroup.org.                                                        *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#ifndef H5Tconv_H
#define H5Tconv_H

#include "H5private.h"
#include "H5Sprivate.h"
#include "H5Tprivate.h"

#define H5T_NAMELEN 32

#define H5_SWAP_BYTES(ARRAY, I, J)                                                                           \
    do {                                                                                                     \
        uint8_t _tmp;                                                                                        \
        _tmp     = ARRAY[I];                                                                                 \
        ARRAY[I] = ARRAY[J];                                                                                 \
        ARRAY[J] = _tmp;                                                                                     \
    } while (0)

struct H5S_t;

typedef struct H5T_conv_cb_t {
    H5T_conv_except_func_t func;
    void                  *user_data;
} H5T_conv_cb_t;

typedef struct H5T_conv_ctx_t {
    union {
        
        struct H5T_conv_ctx_init_fields {
            H5T_conv_cb_t cb_struct;
        } init;

        
        struct H5T_conv_ctx_conv_fields {
            H5T_conv_cb_t cb_struct;
            hid_t         dxpl_id;
            hid_t         src_type_id;
            hid_t         dst_type_id;

            
            bool recursive;
        } conv;

        
        struct H5T_conv_ctx_free_fields {
            hid_t src_type_id;
            hid_t dst_type_id;
        } free;
    } u;
} H5T_conv_ctx_t;

typedef herr_t (*H5T_lib_conv_t)(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata,
                                 const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
                                 size_t bkg_stride, void *buf, void *bkg);

typedef struct H5T_conv_func_t {
    bool is_app; 
    union {
        H5T_conv_t     app_func; 
        H5T_lib_conv_t lib_func; 
    } u;
} H5T_conv_func_t;

#ifdef H5T_DEBUG

typedef struct H5T_stats_t {
    unsigned      ncalls; 
    hsize_t       nelmts; 
    H5_timevals_t times;  
} H5T_stats_t;
#endif

typedef struct H5T_path_t {
    char            name[H5T_NAMELEN]; 
    H5T_t          *src;               
    H5T_t          *dst;               
    H5T_conv_func_t conv;              
    bool            is_hard;           
    bool            is_noop;           
    H5T_cdata_t     cdata;             

#ifdef H5T_DEBUG
    H5T_stats_t stats; 
#endif
} H5T_path_t;

typedef struct H5T_soft_t {
    char            name[H5T_NAMELEN]; 
    H5T_class_t     src;               
    H5T_class_t     dst;               
    H5T_conv_func_t conv;              
} H5T_soft_t;

typedef enum {
    H5T_SUBSET_BADVALUE = -1, 
    H5T_SUBSET_FALSE    = 0,  
    H5T_SUBSET_SRC,           
    H5T_SUBSET_DST,           
    H5T_SUBSET_CAP            
} H5T_subset_t;

typedef struct H5T_subset_info_t {
    H5T_subset_t subset;    
    size_t       copy_size; 
} H5T_subset_info_t;

H5_DLL herr_t H5T_convert(H5T_path_t *tpath, const H5T_t *src_type, const H5T_t *dst_type, size_t nelmts,
                          size_t buf_stride, size_t bkg_stride, void *buf, void *bkg);

H5_DLL herr_t H5T_convert_with_ctx(H5T_path_t *tpath, const H5T_t *src_type, const H5T_t *dst_type,
                                   const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
                                   size_t bkg_stride, void *buf, void *bkg);

H5_DLL H5T_path_t        *H5T_path_find(const H5T_t *src, const H5T_t *dst);
H5_DLL bool               H5T_path_noop(const H5T_path_t *p);
H5_DLL bool               H5T_noop_conv(const H5T_t *src, const H5T_t *dst);
H5_DLL H5T_bkg_t          H5T_path_bkg(const H5T_path_t *p);
H5_DLL H5T_subset_info_t *H5T_path_compound_subset(const H5T_path_t *p);

H5_DLL herr_t H5T_reclaim(const H5T_t *type, struct H5S_t *space, void *buf);
H5_DLL herr_t H5T_reclaim_cb(void *elem, const H5T_t *dt, unsigned ndim, const hsize_t *point, void *op_data);
H5_DLL bool   H5T_get_force_conv(const H5T_t *dt);

H5_DLL herr_t H5T__conv_noop(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata,
                             const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
                             size_t bkg_stride, void *_buf, void *bkg);
H5_DLL herr_t H5T__conv_order(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata,
                              const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
                              size_t bkg_stride, void *_buf, void *bkg);
H5_DLL herr_t H5T__conv_order_opt(const H5T_t *src, const H5T_t *dst, H5T_cdata_t *cdata,
                                  const H5T_conv_ctx_t *conv_ctx, size_t nelmts, size_t buf_stride,
                                  size_t bkg_stride, void *_buf, void *bkg);

H5_DLL herr_t H5T__reverse_order(uint8_t *rev, uint8_t *s, const H5T_t *dtype);

H5_DLL herr_t H5T__print_path_stats(H5T_path_t *path, int *nprint );

H5_DLL int H5T__get_path_table_npaths(void);

#endif 
